Skip to content

feat: initial implementation for AI Assistant#546

Merged
timkim merged 1 commit intostagefrom
ai-assistant
Mar 10, 2026
Merged

feat: initial implementation for AI Assistant#546
timkim merged 1 commit intostagefrom
ai-assistant

Conversation

@davids-ensemble
Copy link
Collaborator

@davids-ensemble davids-ensemble commented Mar 10, 2026

NOTE: This will be improved in further PRs

This PR introduces a new AI Assistant floating chat bot to the Adobe Developer devsite. The assistant appears as a fixed-position chat button in the bottom-right corner of the page and expands into a full chat window when opened.

Key features

  • Floating chat UI: Collapsible chat panel with open/minimize/close controls
  • Streaming responses: Real-time streaming of AI responses with typing indicator and cursor animation
  • RAG-powered: Connects to the devsite RAG API (/v1/inference/retrieve/generate/stream) for context-aware answers about Adobe Developer documentation
  • Conversation history: Session-based chat history persisted in sessionStorage, with context passed to the AI for follow-up questions
  • Suggested questions: Quick-start prompts (e.g., "What can I do with Express Add-ons?", "How do I build an App Builder application?")
  • Markdown rendering: AI responses rendered with Markdown support (via marked) and sanitized with DOMPurify
  • Source citations: Displays source links for AI responses when citations are returned by the API
  • Copy to clipboard: Copy button on AI messages for easy sharing
  • Feature flag: Controlled via localStorage key ai-assistant-enabled; use ENABLE_AI_ASSISTANT() or DISABLE_AI_ASSISTANT() in the console to toggle
  • Accessibility: ARIA labels, keyboard support (Enter to send), and semantic structure

Related Issue

https://jira.corp.adobe.com/browse/ADPGENAI-51
https://jira.corp.adobe.com/browse/DEVSITE-2146

How Has This Been Tested?

  • Manual testing in local/staging environment with the AI assistant enabled via ENABLE_AI_ASSISTANT() in the browser console
  • Verified chat window open/minimize/close behavior
  • Verified streaming responses render correctly with markdown
  • Verified suggested questions trigger queries
  • Verified chat history persists across window minimize/reopen within the same session
  • Verified copy-to-clipboard on AI messages
  • Verified source citations display when returned by the API
  • Verified assistant does not load when IS_AI_ASSISTANT_ENABLED is false (default)

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • I have signed the Adobe Open Source CLA.
  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

URL for testing:

@davids-ensemble davids-ensemble requested a review from timkim March 10, 2026 12:08
@aem-code-sync
Copy link

aem-code-sync bot commented Mar 10, 2026

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch and validate page speed.
In case there are problems, just click a checkbox below to rerun the respective action.

  • Re-run PSI checks
  • Re-sync branch
Commits

@github-actions
Copy link

❌ Test Results

Status: Some tests failed!

🔍 Click to view failed tests
📁 test/blocks/columns/columns.test.js:

❌ Columns block > Columns > columns-container
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at n.<anonymous> (test/blocks/columns/columns.test.js:29:117)

❌ Columns block > Columns > buttons
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at test/blocks/columns/columns.test.js:100:86
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/columns/columns.test.js:95:50)


📁 test/blocks/embed/embed.test.js:

❌ Could not import your test module. Check the browser logs or open the browser in debug mode for more information.


📁 test/blocks/contributors/contributors.test.js:

❌ Contributors block > contributors > firstDiv
      AssertionError: expected null to exist
        at n.<anonymous> (test/blocks/contributors/contributors.test.js:32:28)


📁 test/blocks/tab/tab.test.js:

❌ Tab block > Tab Button Structure > tab > button load structure
      AssertionError: expected 'tab-button active' to equal 'tab-button'
      + expected - actual
      
      -tab-button active
      +tab-button
      
      at n.<anonymous> (test/blocks/tab/tab.test.js:60:38)

❌ Tab block > Sub-tabs > sub-tab > attributes
      AssertionError: expected 'subTab1' to equal 'subTab3'
      + expected - actual
      
      -subTab1
      +subTab3
      
      at test/blocks/tab/tab.test.js:135:58
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/tab/tab.test.js:133:23)



Test Coverage Report

Overall Coverage Summary

Metric Percentage Coverage
Statements 60.32% 3301/5472
Branches 86.42% 433/501
Functions 54.5% 109/200
Lines 60.32% 3301/5472

Coverage by File/Directory

File Statements Branches Functions Lines
blocks/accordion 100% 100% 100% 100%
blocks/announcement 76.69% 60% 100% 76.69%
blocks/banner 94.28% 62.5% 100% 94.28%
blocks/cards 94.04% 94.73% 100% 94.04%
blocks/carousel 76.9% 77.77% 75% 76.9%
blocks/columns 67.51% 78.37% 100% 67.51%
blocks/contributors 100% 100% 100% 100%
blocks/edition 91.22% 57.14% 100% 91.22%
blocks/fragment 19.37% 100% 0% 19.37%
blocks/image-text 57.5% 55.55% 100% 57.5%
blocks/info 96.87% 100% 100% 96.87%
blocks/info-card 73.86% 30% 100% 73.86%
blocks/info-columns 75% 100% 100% 75%
blocks/list 59.09% 85.71% 100% 59.09%
blocks/mini-resource-card 97.89% 87.5% 100% 97.89%
blocks/product-card 78.57% 94.11% 100% 78.57%
blocks/profile-card 96.29% 100% 100% 96.29%
blocks/site-hero 93.93% 80% 100% 93.93%
blocks/summary 98.36% 88.88% 100% 98.36%
blocks/tab 92.76% 88.46% 100% 92.76%
blocks/table 100% 84.61% 100% 100%
blocks/text 49.01% 83.33% 50% 49.01%
blocks/title 84% 66.66% 100% 84%
components 47.58% 100% 57.14% 47.58%
scripts 48.97% 93.15% 43.44% 48.97%

Coverage report generated at 2026-03-10T12:09:44.879Z

@aem-code-sync
Copy link

aem-code-sync bot commented Mar 10, 2026

Page Scores Audits Google
📱 / PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI
🖥️ / PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI

@github-actions
Copy link

❌ Test Results

Status: Some tests failed!

🔍 Click to view failed tests
📁 test/blocks/columns/columns.test.js:

❌ Columns block > Columns > columns-container
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at n.<anonymous> (test/blocks/columns/columns.test.js:29:117)

❌ Columns block > Columns > buttons
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at test/blocks/columns/columns.test.js:100:86
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/columns/columns.test.js:95:50)


📁 test/blocks/embed/embed.test.js:

❌ Could not import your test module. Check the browser logs or open the browser in debug mode for more information.


📁 test/blocks/contributors/contributors.test.js:

❌ Contributors block > contributors > firstDiv
      AssertionError: expected null to exist
        at n.<anonymous> (test/blocks/contributors/contributors.test.js:32:28)


📁 test/blocks/tab/tab.test.js:

❌ Tab block > Tab Button Structure > tab > button load structure
      AssertionError: expected 'tab-button active' to equal 'tab-button'
      + expected - actual
      
      -tab-button active
      +tab-button
      
      at n.<anonymous> (test/blocks/tab/tab.test.js:60:38)

❌ Tab block > Sub-tabs > sub-tab > attributes
      AssertionError: expected 'subTab1' to equal 'subTab3'
      + expected - actual
      
      -subTab1
      +subTab3
      
      at test/blocks/tab/tab.test.js:135:58
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/tab/tab.test.js:133:23)



Test Coverage Report

Overall Coverage Summary

Metric Percentage Coverage
Statements 60.27% 3298/5472
Branches 86.48% 435/503
Functions 54% 108/200
Lines 60.27% 3298/5472

Coverage by File/Directory

File Statements Branches Functions Lines
blocks/accordion 100% 100% 100% 100%
blocks/announcement 76.69% 60% 100% 76.69%
blocks/banner 94.28% 62.5% 100% 94.28%
blocks/cards 94.04% 94.73% 100% 94.04%
blocks/carousel 76.9% 77.77% 75% 76.9%
blocks/columns 67.51% 78.94% 100% 67.51%
blocks/contributors 100% 100% 100% 100%
blocks/edition 91.22% 57.14% 100% 91.22%
blocks/fragment 19.37% 100% 0% 19.37%
blocks/image-text 57.5% 55.55% 100% 57.5%
blocks/info 96.87% 100% 100% 96.87%
blocks/info-card 73.86% 30% 100% 73.86%
blocks/info-columns 75% 100% 100% 75%
blocks/list 59.09% 85.71% 100% 59.09%
blocks/mini-resource-card 97.89% 87.5% 100% 97.89%
blocks/product-card 78.57% 94.11% 100% 78.57%
blocks/profile-card 96.29% 100% 100% 96.29%
blocks/site-hero 93.93% 80% 100% 93.93%
blocks/summary 98.36% 88.88% 100% 98.36%
blocks/tab 92.76% 88.46% 100% 92.76%
blocks/table 100% 84.61% 100% 100%
blocks/text 49.01% 83.33% 50% 49.01%
blocks/title 84% 66.66% 100% 84%
components 47.58% 100% 57.14% 47.58%
scripts 48.88% 93.19% 42.75% 48.88%

Coverage report generated at 2026-03-10T13:49:07.957Z

@davids-ensemble davids-ensemble changed the base branch from main to stage March 10, 2026 19:25
@github-actions
Copy link

❌ Test Results

Status: Some tests failed!

🔍 Click to view failed tests
📁 test/blocks/columns/columns.test.js:

❌ Columns block > Columns > columns-container
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at n.<anonymous> (test/blocks/columns/columns.test.js:29:117)

❌ Columns block > Columns > buttons
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at test/blocks/columns/columns.test.js:100:86
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/columns/columns.test.js:95:50)


📁 test/blocks/embed/embed.test.js:

❌ Could not import your test module. Check the browser logs or open the browser in debug mode for more information.


📁 test/blocks/contributors/contributors.test.js:

❌ Contributors block > contributors > firstDiv
      AssertionError: expected null to exist
        at n.<anonymous> (test/blocks/contributors/contributors.test.js:32:28)


📁 test/blocks/tab/tab.test.js:

❌ Tab block > Tab Button Structure > tab > button load structure
      AssertionError: expected 'tab-button active' to equal 'tab-button'
      + expected - actual
      
      -tab-button active
      +tab-button
      
      at n.<anonymous> (test/blocks/tab/tab.test.js:60:38)

❌ Tab block > Sub-tabs > sub-tab > attributes
      AssertionError: expected 'subTab1' to equal 'subTab3'
      + expected - actual
      
      -subTab1
      +subTab3
      
      at test/blocks/tab/tab.test.js:135:58
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/tab/tab.test.js:133:23)



Test Coverage Report

Overall Coverage Summary

Metric Percentage Coverage
Statements 60.33% 3384/5609
Branches 86.85% 456/525
Functions 54.41% 111/204
Lines 60.33% 3384/5609

Coverage by File/Directory

File Statements Branches Functions Lines
blocks/accordion 100% 100% 100% 100%
blocks/announcement 76.69% 60% 100% 76.69%
blocks/banner 94.28% 62.5% 100% 94.28%
blocks/cards 94.04% 94.73% 100% 94.04%
blocks/carousel 76.9% 77.77% 75% 76.9%
blocks/code 81.81% 60% 100% 81.81%
blocks/columns 67.51% 78.37% 100% 67.51%
blocks/contributors 100% 100% 100% 100%
blocks/edition 91.22% 57.14% 100% 91.22%
blocks/fragment 19.37% 100% 0% 19.37%
blocks/image-text 57.5% 55.55% 100% 57.5%
blocks/info 96.87% 100% 100% 96.87%
blocks/info-card 73.86% 30% 100% 73.86%
blocks/info-columns 75% 100% 100% 75%
blocks/list 59.09% 85.71% 100% 59.09%
blocks/mini-resource-card 97.89% 87.5% 100% 97.89%
blocks/product-card 78.57% 94.11% 100% 78.57%
blocks/profile-card 96.29% 100% 100% 96.29%
blocks/site-hero 93.93% 80% 100% 93.93%
blocks/summary 98.36% 88.88% 100% 98.36%
blocks/tab 95.39% 92.3% 100% 95.39%
blocks/table 100% 84.61% 100% 100%
blocks/text 49.01% 83.33% 50% 49.01%
blocks/title 84% 66.66% 100% 84%
components 64% 100% 66.66% 64%
scripts 48.13% 93.08% 42.46% 48.13%

Coverage report generated at 2026-03-10T20:10:47.638Z

@github-actions
Copy link

❌ Test Results

Status: Some tests failed!

🔍 Click to view failed tests
📁 test/blocks/columns/columns.test.js:

❌ Columns block > Columns > columns-container
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at n.<anonymous> (test/blocks/columns/columns.test.js:29:117)

❌ Columns block > Columns > buttons
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at test/blocks/columns/columns.test.js:100:86
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/columns/columns.test.js:95:50)


📁 test/blocks/embed/embed.test.js:

❌ Could not import your test module. Check the browser logs or open the browser in debug mode for more information.


📁 test/blocks/contributors/contributors.test.js:

❌ Contributors block > contributors > firstDiv
      AssertionError: expected null to exist
        at n.<anonymous> (test/blocks/contributors/contributors.test.js:32:28)

❌ Contributors block > contributors > remove divs without children
      AssertionError: expected false to be true
      + expected - actual
      
      -false
      +true
      
      at test/blocks/contributors/contributors.test.js:42:44
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/contributors/contributors.test.js:41:51)

❌ Contributors block > contributors > last update div
      AssertionError: expected '' to equal 'https://github.com/AdobeDocs/express-add-ons-docs/commits/main/src/pages/references/index.md'
      + expected - actual
      
      +https://github.com/AdobeDocs/express-add-ons-docs/commits/main/src/pages/references/index.md
      
      at n.<anonymous> (test/blocks/contributors/contributors.test.js:53:40)

❌ Contributors block > contributors > image list div
      AssertionError: expected null to exist
        at test/blocks/contributors/contributors.test.js:71:27
        at Array.forEach (<anonymous>)
        at n.<anonymous> (test/blocks/contributors/contributors.test.js:69:33)


📁 test/blocks/tab/tab.test.js:

❌ Tab block > Tab Button Structure > tab > button load structure
      AssertionError: expected 'tab-button active' to equal 'tab-button'
      + expected - actual
      
      -tab-button active
      +tab-button
      
      at n.<anonymous> (test/blocks/tab/tab.test.js:60:38)

❌ Tab block > Sub-tabs > sub-tab > attributes
      AssertionError: expected 'subTab1' to equal 'subTab3'
      + expected - actual
      
      -subTab1
      +subTab3
      
      at test/blocks/tab/tab.test.js:135:58
      at NodeList.forEach (<anonymous>)
      at n.<anonymous> (test/blocks/tab/tab.test.js:133:23)



Test Coverage Report

Overall Coverage Summary

Metric Percentage Coverage
Statements 60.05% 3392/5648
Branches 85.26% 457/536
Functions 54.36% 112/206
Lines 60.05% 3392/5648

Coverage by File/Directory

File Statements Branches Functions Lines
blocks/accordion 100% 100% 100% 100%
blocks/announcement 76.69% 60% 100% 76.69%
blocks/banner 94.28% 62.5% 100% 94.28%
blocks/cards 94.04% 94.73% 100% 94.04%
blocks/carousel 76.9% 77.77% 75% 76.9%
blocks/code 81.81% 60% 100% 81.81%
blocks/columns 67.51% 78.94% 100% 67.51%
blocks/contributors 84.56% 52.38% 100% 84.56%
blocks/edition 91.22% 57.14% 100% 91.22%
blocks/fragment 19.37% 100% 0% 19.37%
blocks/image-text 57.5% 55.55% 100% 57.5%
blocks/info 96.87% 100% 100% 96.87%
blocks/info-card 73.86% 30% 100% 73.86%
blocks/info-columns 75% 100% 100% 75%
blocks/list 59.09% 85.71% 100% 59.09%
blocks/mini-resource-card 97.89% 87.5% 100% 97.89%
blocks/product-card 78.57% 94.11% 100% 78.57%
blocks/profile-card 96.29% 100% 100% 96.29%
blocks/site-hero 93.93% 80% 100% 93.93%
blocks/summary 98.36% 88.88% 100% 98.36%
blocks/tab 95.39% 92.3% 100% 95.39%
blocks/table 100% 84.61% 100% 100%
blocks/text 49.01% 83.33% 50% 49.01%
blocks/title 84% 66.66% 100% 84%
components 64% 100% 66.66% 64%
scripts 48.09% 93.08% 42.17% 48.09%

Coverage report generated at 2026-03-10T22:40:31.474Z

@timkim timkim merged commit 0e269fd into stage Mar 10, 2026
1 of 4 checks passed
@davids-ensemble davids-ensemble deleted the ai-assistant branch March 11, 2026 08:28
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.

2 participants