Skip to content

Add MessageEntry component for unified chatbot#3160

Merged
openshift-merge-bot[bot] merged 1 commit intoopenshift-assisted:masterfrom
rawagner:unified_chatbot
Sep 9, 2025
Merged

Add MessageEntry component for unified chatbot#3160
openshift-merge-bot[bot] merged 1 commit intoopenshift-assisted:masterfrom
rawagner:unified_chatbot

Conversation

@rawagner
Copy link
Member

@rawagner rawagner commented Sep 9, 2025

AssistedInstaller custom msg component that will be exported and loaded by console.redhat.com unified chatbot

Summary by CodeRabbit

  • New Features

    • Rich chat message entries with avatar, timestamp, accessibility labels, loading states, action buttons, and streaming tool actions.
    • Per-message actions: download files and navigate to cluster details.
    • Feedback tools: thumbs up/down, feedback form, and copy-to-clipboard.
  • Improvements

    • Clear loading indicators for in-progress assistant replies.
    • More reliable downloads with error handling.
    • Consistent Markdown handling for user messages.

@coderabbitai
Copy link

coderabbitai bot commented Sep 9, 2025

Walkthrough

Adds a new MessageEntry React component and props to the chatbot library, exports them from the package index, makes MsgAction a public type, introduces per-message action handling (downloads, cluster navigation) and feedback submission to /v1/feedback, and adds two package dependencies.

Changes

Cohort / File(s) Summary
New Message component
libs/chatbot/lib/components/ChatBot/MessageEntry.tsx
Adds default-exported MessageEntry and exported MessageEntryProps; renders messages (avatar, timestamp, aria labels, loading state), parses message.additionalAttributes.toolCalls into actions, renders action buttons (download via saveAs, cluster navigation via openClusterDetails), provides feedback UI (positive/negative/copy) and posts feedback to /v1/feedback using onApiCall.
Public helper type
libs/chatbot/lib/components/ChatBot/helpers.ts
Makes MsgAction a public exported type (export type MsgAction = { title: string; url?: string; clusterId?: string }) without changing its shape.
Public exports
libs/chatbot/lib/index.ts
Re-exports MessageEntry (default) and MessageEntryProps type from ./components/ChatBot/MessageEntry.
Package deps
libs/chatbot/package.json
Adds dependencies @redhat-cloud-services/ai-client-state and @redhat-cloud-services/lightspeed-client (both ^0.14.0).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant ChatUI as Chat UI
  participant MessageEntry as MessageEntry component
  participant Parser as ToolCalls Parser
  participant Browser as saveAs / Clipboard
  participant App as openClusterDetails callback
  participant API as /v1/feedback

  User->>ChatUI: View conversation
  ChatUI->>MessageEntry: Render message {message, avatar, openClusterDetails, onApiCall}
  MessageEntry->>Parser: Parse message.additionalAttributes.toolCalls
  Parser-->>MessageEntry: Actions [{title, url?, clusterId?}]

  alt Click Download
    User->>MessageEntry: Click "Download"
    MessageEntry->>Browser: saveAs(url)
    Browser-->>MessageEntry: Success / Error
  end

  alt Click Cluster action
    User->>MessageEntry: Click "Open cluster details"
    MessageEntry->>App: openClusterDetails(clusterId)
  end

  alt Feedback / Copy
    User->>MessageEntry: Click Positive/Negative/Copy
    MessageEntry->>Browser: copy answer to clipboard (on Copy)
    MessageEntry->>API: POST /v1/feedback {conversation_id, user_question, user_feedback, llm_response, sentiment, category} (on submit)
    API-->>MessageEntry: 200 OK / Error
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • ammont82
  • celdrake

Pre-merge checks (3 passed)

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly and concisely states the primary change—adding the MessageEntry component for the unified chatbot—without unnecessary detail or vague language, making it easy for reviewers to understand the core purpose of the pull request.
Description Check ✅ Passed The description directly relates to the changeset by explaining that a custom message component will be exported and loaded by the console’s unified chatbot, which aligns with the addition of the MessageEntry component.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

Poem

I nibble bytes and stitch a line,
I show the answer, timestamp fine.
Click to save or jump to a cluster view,
I send your feedback — quick and true.
A rabbit hops to cheer this new review. 🐇


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f5c6ad and ce01f81.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • libs/chatbot/lib/components/ChatBot/MessageEntry.tsx (1 hunks)
  • libs/chatbot/lib/components/ChatBot/helpers.ts (1 hunks)
  • libs/chatbot/lib/index.ts (1 hunks)
  • libs/chatbot/package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • libs/chatbot/package.json
  • libs/chatbot/lib/index.ts
  • libs/chatbot/lib/components/ChatBot/helpers.ts
  • libs/chatbot/lib/components/ChatBot/MessageEntry.tsx
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci bot requested review from ammont82 and asmasarw September 9, 2025 10:38
@openshift-ci openshift-ci bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. labels Sep 9, 2025
@rawagner
Copy link
Member Author

rawagner commented Sep 9, 2025

/cherry-pick releases/v0.1-chatbot

@openshift-cherrypick-robot
Copy link
Contributor

@rawagner: once the present PR merges, I will cherry-pick it on top of releases/v0.1-chatbot in a new PR and assign it to you.

Details

In response to this:

/cherry-pick releases/v0.1-chatbot

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (5)
libs/chatbot/lib/components/ChatBot/MessageEntry.tsx (5)

25-38: Consider timeout/abort for the POST to improve resiliency.

Add an AbortController with a reasonable timeout so stuck requests don’t hang the UI.

Apply this diff:

-      const resp = await onApiCall('/v1/feedback', {
+      const controller = new AbortController();
+      const timeoutId = window.setTimeout(() => controller.abort(), 15000);
+      const resp = await onApiCall('/v1/feedback', {
         method: 'POST',
         body: JSON.stringify({
@@
         headers: {
           'Content-Type': 'application/json',
         },
-      });
+        signal: controller.signal,
+      });
+      window.clearTimeout(timeoutId);

46-46: Avoid “undefined undefined” timestamps when date is missing.

Guard message.date.

Apply this diff:

-  const messageDate = `${message.date?.toLocaleDateString()} ${message.date?.toLocaleTimeString()}`;
+  const messageDate = message.date
+    ? `${message.date.toLocaleDateString()} ${message.date.toLocaleTimeString()}`
+    : undefined;

95-97: Handle clipboard write failures.

Older browsers or denied permissions can reject the promise.

Apply this diff:

-            onClick: () => {
-              void navigator.clipboard.writeText(message.answer || '');
-            },
+            onClick: () => {
+              navigator.clipboard
+                .writeText(message.answer || '')
+                // eslint-disable-next-line no-console
+                .catch((e) => console.error('Copy failed:', e));
+            },

111-113: Keep aria-label concise.

Very long responses make the label noisy; truncate for SR usability.

Apply this diff:

-        aria-label={`${message.role === 'user' ? 'Your message' : 'AI response'}: ${
-          message.answer
-        }`}
+        aria-label={`${message.role === 'user' ? 'Your message' : 'AI response'}: ${
+          message.answer?.slice(0, 120) ?? ''
+        }${message.answer && message.answer.length > 120 ? '…' : ''}`}

121-123: Use a more stable React key for actions.

Avoid index keys to reduce reconciliation glitches.

Apply this diff:

-                  {actions.map(({ title, url, clusterId }, idx) => (
-                    <StackItem key={idx}>
+                  {actions.map(({ title, url, clusterId }, idx) => (
+                    <StackItem key={`${title}-${url ?? clusterId ?? idx}`}>
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9b11b9d and 0f5c6ad.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (4)
  • libs/chatbot/lib/components/ChatBot/MessageEntry.tsx (1 hunks)
  • libs/chatbot/lib/components/ChatBot/helpers.ts (1 hunks)
  • libs/chatbot/lib/index.ts (1 hunks)
  • libs/chatbot/package.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • libs/chatbot/package.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • libs/chatbot/lib/components/ChatBot/helpers.ts
  • libs/chatbot/lib/index.ts
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: celdrake
PR: openshift-assisted/assisted-installer-ui#3051
File: libs/chatbot/lib/components/ChatBot/ChatBotWindow.tsx:196-222
Timestamp: 2025-07-18T12:35:50.945Z
Learning: In the assisted-installer-ui chatbot feedback implementation, the onFeedbackSubmit callback requires access to the messages array to retrieve both the bot response content and the associated user question for the API call, making it necessary to include messages in the useCallback dependency array rather than passing message content as props to avoid duplicating potentially long message data.
🧬 Code graph analysis (1)
libs/chatbot/lib/components/ChatBot/MessageEntry.tsx (3)
libs/chatbot/lib/components/ChatBot/BotMessage.tsx (1)
  • FeedbackRequest (16-20)
libs/chatbot/lib/components/ChatBot/types.ts (3)
  • StreamEvent (21-26)
  • isToolArgStreamEvent (33-34)
  • isToolResponseStreamEvent (36-37)
libs/chatbot/lib/components/ChatBot/helpers.ts (2)
  • MsgAction (5-5)
  • getToolAction (32-99)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: tests
🔇 Additional comments (2)
libs/chatbot/lib/components/ChatBot/MessageEntry.tsx (2)

6-7: Verify PF v6 component API usage.

Imports are from @patternfly-6/*. Please confirm the Button icon prop and other APIs match PF v6 in this repo’s env to avoid runtime prop warnings.


105-107: Good call disabling Markdown for user messages.

Prevents user-supplied Markdown from rendering.

Copy link
Contributor

@celdrake celdrake left a comment

Choose a reason for hiding this comment

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

Looks good!
Just a small comment that maybe we could show the error in case the download is interrupted.

@openshift-ci openshift-ci bot added the lgtm Indicates that a PR is ready to be merged. label Sep 9, 2025
@openshift-ci
Copy link

openshift-ci bot commented Sep 9, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: celdrake, rawagner

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@rawagner
Copy link
Member Author

rawagner commented Sep 9, 2025

Looks good! Just a small comment that maybe we could show the error in case the download is interrupted.

Thanks, I'll improve the err handling in a followup

@openshift-merge-bot openshift-merge-bot bot merged commit bc6af0b into openshift-assisted:master Sep 9, 2025
11 checks passed
@openshift-cherrypick-robot
Copy link
Contributor

@rawagner: new pull request created: #3161

Details

In response to this:

/cherry-pick releases/v0.1-chatbot

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants