Skip to content

feat(intelligent-assistant): slim MF sync bundles (RHIDP-15550) - #4764

Open
rohitratannagar wants to merge 13 commits into
redhat-developer:mainfrom
rohitratannagar:feat/RHIDP-15550-mf-bundle-optimization
Open

rohitratannagar wants to merge 13 commits into
redhat-developer:mainfrom
rohitratannagar:feat/RHIDP-15550-mf-bundle-optimization

Conversation

@rohitratannagar

Copy link
Copy Markdown
Contributor

Ticket

RHIDP-15550 — Reduce Intelligent Assistant Module Federation synchronous payload for NFS main entry, FAB remote, and translations remote.

Problem

FAB and translations MF exposes previously resolved through index.tsx, so each remote pulled the full plugin graph (chat UI, Patternfly CSS, FAB modules, translations) into the sync bundle. The NFS . expose was ~3.7 MB across 6 synchronous chunks before this change.

Overall impact (post plugin export, sync chunks only)

Expose Before (approx.) After (approx.) Change
NFS . (PluginRoot) ~3722 KB, 6 sync chunks ~95 KB, 3 sync chunks ~97% smaller sync
IntelligentAssistantFABModule ~3722 KB ~15 KB ~99.6% smaller sync
IntelligentAssistantTranslationsModule ~3722 KB ~31 KB ~99.2% smaller sync

Heavy chat/Patternfly assets move to async chunks loaded when the user opens chat (drawer or overlay). OFS legacy entry remains a thin lazy re-export surface.

What each file does

File Role in optimization
src/index.tsx Slim NFS entry: APIs, page blueprint, drawer blueprint only; re-exports FAB/translations modules from dedicated files instead of defining them inline.
src/fabModule.tsx Dedicated MF graph for FAB + legacy redirect modules (LazyLightspeedFabRootWrapper).
src/translationsModule.tsx Dedicated MF graph for translations module only (must not import index.tsx).
src/lightspeedFABModuleExport.ts Thin expose path → fabModule.tsx.
src/lightspeedTranslationsModuleExport.ts Thin expose path → translationsModule.tsx.
src/lazy/LazyLightspeedFabRootWrapper.tsx React.lazy boundary for drawer provider + FAB shell.
src/lazy/LazyLightspeedChatDrawerContent.tsx Thin docked-drawer shell that lazy-loads LightspeedChatContainer.
src/components/LightspeedOverlayChat.tsx Overlay ChatbotModal + chat; lazy-loaded from drawer provider.
src/components/LightspeedDrawerProvider.tsx Loads overlay chat asynchronously instead of bundling it in the provider sync graph.
src/components/LightspeedChatContainer.tsx Triggers deferred Patternfly/chatbot CSS via loadChatPatternflyStyles.
src/loadChatPatternflyStyles.ts Dynamic import of PF/chatbot styles (removed from entry sync graph).
src/muiClassNameConfig.ts Shared MUI class-name side effect imported by slim entries (not duplicated in heavy paths).
src/legacy.ts OFS legacy expose: lazy re-exports to avoid pulling NFS graph.

Test plan

  • yarn test in plugins/intelligent-assistant (882 tests)
  • yarn build / workspace plugin export; confirm mf-manifest.json sync sizes for ., FAB, and translations exposes
  • Manual: FAB visible; docked drawer opens chat; overlay mode works; translations load in app shell
  • Smoke NFS + OFS hosts if applicable

Made with Cursor

@rhdh-gh-app

rhdh-gh-app Bot commented Sep 15, 2026

Copy link
Copy Markdown

Changed Packages

Package Name Package Path Changeset Bump Current Version
app workspaces/intelligent-assistant/packages/app none v0.0.0
@red-hat-developer-hub/backstage-plugin-intelligent-assistant workspaces/intelligent-assistant/plugins/intelligent-assistant patch v5.2.0

@rohitratannagar
rohitratannagar force-pushed the feat/RHIDP-15550-mf-bundle-optimization branch from 95e189f to a5b99e5 Compare September 15, 2026 09:14
@codecov

codecov Bot commented Sep 15, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.61538% with 32 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.94%. Comparing base (ccdf948) to head (9b3a13f).
⚠️ Report is 12 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #4764   +/-   ##
=======================================
  Coverage   63.94%   63.94%           
=======================================
  Files        2705     2714    +9     
  Lines      108465   108549   +84     
  Branches    30398    30396    -2     
=======================================
+ Hits        69353    69408   +55     
- Misses      37342    37370   +28     
- Partials     1770     1771    +1     
Flag Coverage Δ *Carryforward flag
adoption-insights 84.77% <ø> (ø) Carriedforward from b4a3e40
ai-integrations 84.34% <ø> (ø) Carriedforward from b4a3e40
app-defaults 63.63% <ø> (ø) Carriedforward from b4a3e40
augment 46.67% <ø> (ø) Carriedforward from b4a3e40
boost 84.97% <ø> (ø) Carriedforward from b4a3e40
bulk-import 73.12% <ø> (ø) Carriedforward from b4a3e40
cost-management 13.53% <ø> (ø) Carriedforward from b4a3e40
dcm 73.47% <ø> (ø) Carriedforward from b4a3e40
e2e-adoption-insights 60.00% <ø> (ø) Carriedforward from b4a3e40
e2e-extensions 62.31% <ø> (ø) Carriedforward from b4a3e40
e2e-global-header 51.82% <ø> (ø) Carriedforward from b4a3e40
e2e-homepage 61.11% <ø> (ø) Carriedforward from b4a3e40
e2e-intelligent-assistant 45.57% <ø> (-0.40%) ⬇️ Carriedforward from b4a3e40
e2e-orchestrator 49.49% <ø> (ø) Carriedforward from b4a3e40
e2e-orchestrator-plugin 49.48% <ø> (ø) Carriedforward from b4a3e40
e2e-quickstart 55.21% <ø> (ø) Carriedforward from b4a3e40
e2e-scorecard 49.83% <ø> (ø) Carriedforward from b4a3e40
e2e-theme 16.36% <ø> (ø) Carriedforward from b4a3e40
extensions 58.30% <ø> (ø) Carriedforward from b4a3e40
global-floating-action-button 71.18% <ø> (ø) Carriedforward from b4a3e40
global-header 67.76% <ø> (ø) Carriedforward from b4a3e40
homepage 55.05% <ø> (ø) Carriedforward from b4a3e40
install-dynamic-plugins 73.52% <ø> (ø) Carriedforward from b4a3e40
intelligent-assistant 78.66% <84.61%> (-0.10%) ⬇️
konflux 91.98% <ø> (ø) Carriedforward from b4a3e40
lightspeed 69.02% <ø> (ø) Carriedforward from b4a3e40
mcp-integrations 84.46% <ø> (ø) Carriedforward from b4a3e40
orchestrator 77.69% <ø> (ø) Carriedforward from b4a3e40
quickstart 63.74% <ø> (ø) Carriedforward from b4a3e40
sandbox 79.56% <ø> (ø) Carriedforward from b4a3e40
scorecard 88.94% <ø> (ø) Carriedforward from b4a3e40
theme 87.94% <ø> (ø) Carriedforward from b4a3e40
translations 5.12% <ø> (ø) Carriedforward from b4a3e40
x2a 78.44% <ø> (ø) Carriedforward from b4a3e40

*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 ccdf948...9b3a13f. 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.

@debsmita1

Copy link
Copy Markdown
Member

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Sep 17, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 5:04 PM UTC · Completed 5:26 PM UTC

Commit: 370620d · View workflow run →

Runtime: claude · Model: opus → claude-opus-4-6 · Effort: high · Cost: $6.35

@fullsend-ai-review fullsend-ai-review Bot added the risk/moderate PR risk: moderate label Sep 17, 2026
@fullsend-ai-review

Copy link
Copy Markdown

Risk Assessment: moderate (2/5)

Details

Moderate risk: a large-blast-radius MF refactor across 17 files with active multi-author churn and sparse test coverage, offset by no security, CI, or dependency exposure and a well-scoped performance objective.

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

Medium

  • [error handling gap] workspaces/intelligent-assistant/plugins/intelligent-assistant/src/loadChatPatternflyStyles.ts:23loadChatPatternflyStyles() caches the promise in a module-level variable. If either CSS dynamic import rejects (network error, missing asset in a Module Federation environment), the rejected promise is cached permanently. In LightspeedChatContainer, the .then() chain has no .catch(), so stylesReady never becomes true and the component returns null permanently with no recovery path. Subsequent calls return the same rejected promise, preventing retry even on component remount.
    Remediation: Add error handling in loadChatPatternflyStyles — reset loadPromise to undefined on rejection so retries are possible. In LightspeedChatContainer, add a .catch() handler and consider surfacing an error state instead of silently rendering null.

  • [behavioral contract change] workspaces/intelligent-assistant/plugins/intelligent-assistant/report-legacy.api.md:28LightspeedChatContainer return type widens from () => JSX_2.Element to () => JSX_2.Element | null. The component now returns null while PatternFly CSS assets load asynchronously. Consumers that render LightspeedChatContainer and immediately query the DOM will observe an empty render window instead of the expected element tree.
    Remediation: Document the null-during-loading window in the public JSDoc comment for LightspeedChatContainer. Consider accepting a fallback prop so callers can supply a loading skeleton instead of null.

Low

  • [z-index stacking] workspaces/intelligent-assistant/plugins/intelligent-assistant/src/components/LightspeedFABContent.tsx:117 — The FAB z-index was changed from theme.zIndex.tooltip (MUI default: 1500) to a hardcoded 200. The overlay chat modal uses 300. Both values are well below MUI's default z-index range for overlays (drawer: 1200, modal: 1300, snackbar: 1400, tooltip: 1500). The FAB-to-overlay ordering is correct, but both may render beneath MUI Dialogs, Snackbars, or Tooltips from other plugins.

  • [test coverage] workspaces/intelligent-assistant/plugins/intelligent-assistant/src/components/__tests__/LightspeedDrawerProvider.test.tsx:79 — The test mocks '../LightspeedChatContainer' but LightspeedDrawerProvider no longer imports it directly. The mock works indirectly because LightspeedOverlayChat imports LightspeedChatContainer, and Jest resolves both paths to the same module. The indirection makes the mock relationship non-obvious.

  • [title mismatch] workspaces/intelligent-assistant/.changeset/rhidp-15550-mf-sync-optimization.md — The PR title uses the feat conventional-commit prefix, but the change is a refactoring/optimization with no new user-facing functionality. The changeset correctly classifies it as patch.

  • [convention] — AGENTS.md mandates an Assisted-by: <model> footer on all commits in this workspace. Verify every commit has the required footer.

  • [re-export identity change] workspaces/intelligent-assistant/plugins/intelligent-assistant/src/legacy.tsLightspeedFAB, LightspeedChatContainer, and LightspeedDrawerStateExposer are now re-exported from ./plugin (wrapped via createComponentExtension) instead of their component files directly. Component object identity changes for legacy API consumers.


Next steps:

  • /fs-fix — agent addresses review findings automatically
  • /fs-fix <your instruction> — agent fixes with your specific guidance
  • Push commits directly — review re-runs automatically on push
  • /fs-fix-stop — disable automatic fix runs for this PR

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: The following review comments could not be posted on the diff (GitHub returned 422) and are included here instead:

  • workspaces/intelligent-assistant/plugins/intelligent-assistant/src/components/__tests__/LightspeedDrawerProvider.test.tsx (file-level): Line 79 · [low] test coverage

The test mocks ../LightspeedChatContainer but LightspeedDrawerProvider no longer imports it directly. The mock works indirectly via LightspeedOverlayChat but the relationship is fragile and non-obvious.

@fullsend-ai-review fullsend-ai-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the review comment for full details.

@rohitratannagar
rohitratannagar force-pushed the feat/RHIDP-15550-mf-bundle-optimization branch 6 times, most recently from 19bd51e to 805dfaa Compare September 18, 2026 07:37

@debsmita1 debsmita1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. In slow network, when the FAB is clicked, the empty chatbot with loader is displayed after several seconds
Screen.Recording.2026-09-18.at.12.44.33.PM.mov

Also, could you check the drawer? It might need a progress bar as well.

  1. In the useLightspeedProviderState hook ChatbotDisplayMode is imported from PF chatbot

import { ChatbotDisplayMode } from '@patternfly/chatbot';

The hook lives in the LightspeedDrawerProvider async chunk, so PF is not on the sync graph, but it is loaded on every page mount (with the FAB), not on chat open.

Could you try moving ChatbotDisplayMode to a local enum/const in const.ts if the enum values are stable. That could slim the always-loaded FAB chunk further.

Comment thread workspaces/intelligent-assistant/plugins/intelligent-assistant/src/index.tsx Outdated
rohitratannagar and others added 2 commits September 18, 2026 15:00
…ranslations

RHIDP-15550: split entry modules and lazy-load chat so remotes no longer
pull the full plugin graph at load time.

Co-authored-by: Cursor <cursoragent@cursor.com>
Revert FAB z-index to pre-MUI v5 so ChatbotModal sits above the button, and re-measure anchor vars when the overlay opens.

Co-authored-by: Cursor <cursoragent@cursor.com>
@rohitratannagar
rohitratannagar force-pushed the feat/RHIDP-15550-mf-bundle-optimization branch from 376f348 to a0ed95c Compare September 18, 2026 09:31
Share one critical FAB async chunk, keep FAB/translations off the NFS
index expose, use a local ChatbotDisplayMode on the FAB path, and show
progress while overlay/drawer chat chunks load.

Assisted-by: Composer
Co-authored-by: Cursor <cursoragent@cursor.com>
@rohitratannagar
rohitratannagar force-pushed the feat/RHIDP-15550-mf-bundle-optimization branch from a0ed95c to 4e8eefb Compare September 18, 2026 09:37
…lure

Keep PF CSS out of the always-mounted notebook stream store and share one
overlay CSS chunk so css-extract-rspack-plugin no longer fails under CI.

Assisted-by: Composer
Co-authored-by: Cursor <cursoragent@cursor.com>
Drop prettier-only whitespace drift introduced during the upstream merge.

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

@its-mitesh-kumar its-mitesh-kumar left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/lgtm

S_.2026-09-21.at.1.mp4

…trict mode

Stop waitForChatbotVisible from navigating to the fullscreen IA route while
the overlay mounts, and match the settings tab button with exact: true.

Signed-off-by: HusneShabbir <husneshabbir447@gmail.com>
Assisted-by: Composer
Co-authored-by: Cursor <cursoragent@cursor.com>
@openshift-ci openshift-ci Bot removed the lgtm label Sep 21, 2026
@openshift-ci

openshift-ci Bot commented Sep 21, 2026

Copy link
Copy Markdown

New changes are detected. LGTM label has been removed.

Run permission gating on dedicated ports so the suite cannot reuse a
main e2e/yarn start instance without permission.enabled, and arm the
authorize waiter before navigation to avoid races.

Assisted-by: Composer
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.

3 participants