Skip to content

feat(lightspeed): notebook chat - #2754

Merged
karthikjeeyar merged 16 commits into
redhat-developer:mainfrom
its-mitesh-kumar:feat/lightspeed-notebook-chat
Apr 28, 2026
Merged

feat(lightspeed): notebook chat#2754
karthikjeeyar merged 16 commits into
redhat-developer:mainfrom
its-mitesh-kumar:feat/lightspeed-notebook-chat

Conversation

@its-mitesh-kumar

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

Copy link
Copy Markdown
Member

Description

Adds the Notebook Chat feature to the Lightspeed plugin, enabling users to interact with AI Notebooks through a chat interface.

Steps to test

  1. clone lightspeed-configs, follwed the README.md and contribute.md instructions (make get-rag, make local-up) after setting up the env variablesclone lightspeed-configs, follwed the README.md instructions (make get-rag, make local-up) after setting up the env variables

a. Create a file env/values.env with below content


# Note: You only need to set the variables you normally would with '-e' flags.
# You do not need to set them all if they will go unused.

# Service Images
LIGHTSPEED_CORE_IMAGE=quay.io/lightspeed-core/lightspeed-stack:0.5.1
RAG_CONTENT_IMAGE=quay.io/redhat-ai-dev/rag-content:release-1.9-lls-0.5.0-642c567fe10a62b5ff711654306b72912f341e05

# Enable Inference Providers
## Set any providers you want enabled to 'true'
## E.g. ENABLE_VLLM=true
## Leave all disabled providers EMPTY
## E.g. ENABLE_OPENAI=
ENABLE_VLLM=true
ENABLE_VERTEX_AI=
ENABLE_OPENAI=
ENABLE_OLLAMA=
ENABLE_VALIDATION=

# vLLM Inference Settings
VLLM_URL=http://host.containers.internal:11434/v1
VLLM_API_KEY=unused
# vLLM Optional Variables
VLLM_MAX_TOKENS=
VLLM_TLS_VERIFY=

# OpenAI Inference Settings
OPENAI_API_KEY=

# Vertex AI Inference Settings
VERTEX_AI_PROJECT=
VERTEX_AI_LOCATION=
GOOGLE_APPLICATION_CREDENTIALS=

# Ollama Inference Settings
OLLAMA_URL=

# Question Validation Safety Shield Settings
## Ensure VALIDATION_PROVIDER is one of your enabled Inference Providers
## Only required for Llama Stack configs that use the Lightspeed Core provider
## E.g. VALIDATION_PROVIDER=vllm if ENABLE_VLLM=true
VALIDATION_PROVIDER=
VALIDATION_MODEL_NAME=

# Other
LLAMA_STACK_LOGGING=

b. Pull the RAG content:

make get-rag

c. OLLAMA_HOST=0.0.0.0 ollama serve

d. Start the local API stack:

make local-up

  1. Add config in the app-config
lightspeed:
  notebooks:
    enabled: true
    queryDefaults:
      model: llama3.2:3b
      provider_id: vllm
    sessionDefaults:
      provider_id: notebooks
      embedding_model: sentence-transformers//rag-content/embeddings_model
      embedding_dimension: 768
  servers:
    - id: vllm
      url: http://localhost:11434/v1
      token: unused
  1. yarn start:legacy

UI after changes

Screen.Recording.2026-04-24.at.11.29.23.PM.mov
Screen.Recording.2026-04-25.at.12.45.52.AM.mov
Screen.Recording.2026-04-25.at.12.49.07.AM.mov

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

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

Copy link
Copy Markdown
Contributor

This pull request adds a new top-level directory under workspaces/. Please follow Submitting a Pull Request for a New Workspace in CONTRIBUTING.md.

@rhdh-qodo-merge

Copy link
Copy Markdown

Review Summary by Qodo

Add notebook chat feature with document management and UI components

✨ Enhancement 🧪 Tests 📝 Documentation

Grey Divider

Walkthroughs

Description
• Implemented comprehensive notebook chat feature with document management capabilities
• Added NotebooksApiClient with new methods for session and document operations: createSession,
  uploadDocument, listDocuments, deleteDocument, getDocumentStatus, and querySession
• Extended NotebooksAPI interface with document operations and session management
• Created notebook-specific types for documents, sessions, and responses
• Implemented file upload validation utilities with support for file type, size, and count
  constraints
• Added React Query hooks for notebook operations: useCreateNotebook, useUploadDocument,
  useDocumentStatusPolling, useNotebookDocuments, and useCreateNotebookMessage
• Built complete UI components for notebook functionality: NotebookView, AddDocumentModal,
  DocumentSidebar, OverwriteConfirmModal, FileTypeIcon, UploadResourceScreen
• Integrated notebook view into main LightSpeedChat component with notebook creation and selection
• Added comprehensive test coverage for utilities, hooks, and components
• Provided translations in 6 languages (English, Japanese, German, French, Spanish, Italian) for all
  notebook UI elements
• Enhanced useConversationMessages hook with createMessageOverride parameter for custom message
  creation logic
• Configured backend notebook query defaults and metadata handling
Diagram
flowchart LR
  A["NotebooksApiClient"] -- "session & document methods" --> B["NotebooksAPI Interface"]
  B -- "uses" --> C["Notebook Types"]
  D["File Upload Utils"] -- "validates" --> E["AddDocumentModal"]
  E -- "uploads via" --> A
  F["useCreateNotebook"] -- "creates" --> A
  G["useUploadDocument"] -- "uploads" --> A
  H["useDocumentStatusPolling"] -- "tracks" --> A
  I["useNotebookDocuments"] -- "lists" --> A
  J["useCreateNotebookMessage"] -- "queries" --> A
  E --> K["NotebookView"]
  L["DocumentSidebar"] -- "displays" --> K
  M["OverwriteConfirmModal"] -- "confirms" --> K
  K -- "integrated into" --> N["LightSpeedChat"]
  O["Translations"] -- "supports" --> K
Loading

Grey Divider

File Changes

1. workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts ✨ Enhancement +144/-19

Expand NotebooksApiClient with document and session management

• Refactored error handling into a reusable handleResponseError method
• Added fetchFormData method for handling FormData uploads with 202 status support
• Implemented new API methods: createSession, uploadDocument, listDocuments, deleteDocument,
 getDocumentStatus, and querySession
• Enhanced fetchJson to handle empty responses gracefully

workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts


2. workspaces/lightspeed/plugins/lightspeed/src/api/notebooksApi.ts ✨ Enhancement +27/-1

Extend NotebooksAPI interface with document operations

• Added createSession method to the NotebooksAPI interface
• Extended API with document operations: uploadDocument, listDocuments, deleteDocument,
 getDocumentStatus
• Added querySession method for streaming responses

workspaces/lightspeed/plugins/lightspeed/src/api/notebooksApi.ts


3. workspaces/lightspeed/plugins/lightspeed/src/types.ts ✨ Enhancement +73/-0

Add notebook document and session response types

• Added conversation_id field to NotebookSessionMetadata
• Introduced new types: NotebookDocumentSourceType, SessionDocument, UploadDocumentResponse,
 DocumentStatus, SessionResponse, DocumentListResponse

workspaces/lightspeed/plugins/lightspeed/src/types.ts


View more (35)
4. workspaces/lightspeed/plugins/lightspeed/src/const.ts ⚙️ Configuration changes +28/-0

Add notebook upload configuration constants

• Added notebook constraints: NOTEBOOK_MAX_FILES (10), NOTEBOOK_MAX_FILE_SIZE_BYTES (25 MB),
 UNTITLED_NOTEBOOK_NAME
• Defined NOTEBOOK_ALLOWED_EXTENSIONS mapping MIME types to file extensions
• Created NOTEBOOK_EXTENSION_TO_FILE_TYPE mapping for file type conversion

workspaces/lightspeed/plugins/lightspeed/src/const.ts


5. workspaces/lightspeed/plugins/lightspeed/src/utils/notebook-upload-utils.ts ✨ Enhancement +94/-0

Create notebook file upload validation utilities

• Implemented file validation functions: validateFileType, validateFileSize, validateFileCount
• Created validateFiles function returning valid files and error messages
• Added getNotebookAcceptedFileTypes helper for file input accept attributes

workspaces/lightspeed/plugins/lightspeed/src/utils/notebook-upload-utils.ts


6. workspaces/lightspeed/plugins/lightspeed/src/utils/__tests__/notebook-upload-utils.test.ts 🧪 Tests +153/-0

Add notebook upload validation unit tests

• Comprehensive test coverage for file type validation (case-insensitive, extension checking)
• Tests for file size validation against 25 MB limit
• Tests for file count validation against maximum file limit
• Tests for combined validation scenarios and error reporting

workspaces/lightspeed/plugins/lightspeed/src/utils/tests/notebook-upload-utils.test.ts


7. workspaces/lightspeed/plugins/lightspeed/src/utils/__tests__/notebooks-utils.test.ts 🧪 Tests +62/-0

Add notebook utilities unit tests

• Tests for formatUpdatedLabel function with various date scenarios
• Coverage for today, yesterday, days ago, and older date formatting
• Tests for invalid date handling

workspaces/lightspeed/plugins/lightspeed/src/utils/tests/notebooks-utils.test.ts


8. workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useCreateNotebook.ts ✨ Enhancement +49/-0

Add useCreateNotebook hook for session creation

• Created hook for notebook creation mutation using React Query
• Handles session creation with name and optional description
• Invalidates sessions query on successful creation

workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useCreateNotebook.ts


9. workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useUploadDocument.ts ✨ Enhancement +59/-0

Add useUploadDocument hook for file uploads

• Implemented mutation hook for document uploads
• Converts file extensions to appropriate file types
• Invalidates document list query on successful upload

workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useUploadDocument.ts


10. workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useDocumentStatusPolling.ts ✨ Enhancement +79/-0

Add useDocumentStatusPolling hook for upload tracking

• Created hook for polling document processing status
• Implements adaptive polling with 5-second intervals
• Stops polling when document reaches terminal state (completed, failed, cancelled)
• Returns polling results with status and document metadata

workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useDocumentStatusPolling.ts


11. workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useNotebookDocuments.ts ✨ Enhancement +36/-0

Add useNotebookDocuments hook for document listing

• Created query hook for fetching documents in a notebook session
• Implements caching with 1-minute stale time
• Conditionally enabled based on session ID availability

workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useNotebookDocuments.ts


12. workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useCreateNotebookMessage.ts ✨ Enhancement +51/-0

Add useCreateNotebookMessage hook for queries

• Implemented mutation hook for querying notebook sessions
• Returns readable stream for streaming responses
• Includes error handling and logging

workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useCreateNotebookMessage.ts


13. workspaces/lightspeed/plugins/lightspeed/src/hooks/useCreateCoversationMessage.ts ✨ Enhancement +1/-1

Export CreateMessageVariables type

• Exported CreateMessageVariables type for external use

workspaces/lightspeed/plugins/lightspeed/src/hooks/useCreateCoversationMessage.ts


14. workspaces/lightspeed/plugins/lightspeed/src/hooks/useConversationMessages.ts ✨ Enhancement +9/-2

Add createMessageOverride parameter to useConversationMessages

• Added optional createMessageOverride parameter for custom message creation
• Allows notebook view to use its own message creation logic

workspaces/lightspeed/plugins/lightspeed/src/hooks/useConversationMessages.ts


15. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookView.tsx ✨ Enhancement +641/-0

Add NotebookView component with chat and documents

• Comprehensive notebook view component with chat interface
• Implements document sidebar with collapsible state and file management
• Handles file uploads with validation, overwrite confirmation, and status polling
• Displays toast alerts for upload success/failure
• Integrates with conversation messages and welcome prompts

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookView.tsx


16. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/AddDocumentModal.tsx ✨ Enhancement +198/-0

Add AddDocumentModal for file uploads

• Modal component for adding documents to notebooks
• Implements drag-and-drop file upload with PatternFly components
• Validates files and displays error alerts
• Handles duplicate file detection and confirmation flow

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/AddDocumentModal.tsx


17. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/DocumentSidebar.tsx ✨ Enhancement +193/-0

Add DocumentSidebar component

• Sidebar component displaying notebook documents and upload status
• Shows document count and file type icons
• Displays spinners for in-progress uploads
• Collapsible with add document button

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/DocumentSidebar.tsx


18. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/OverwriteConfirmModal.tsx ✨ Enhancement +167/-0

Add OverwriteConfirmModal for duplicate handling

• Modal for confirming file overwrites
• Displays list of files to be overwritten with file type icons
• Provides overwrite and cancel actions

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/OverwriteConfirmModal.tsx


19. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/FileTypeIcon.tsx ✨ Enhancement +80/-0

Add FileTypeIcon component for file visualization

• Component rendering file type badges with color coding
• Supports multiple file types with distinct colors
• Displays file extension or "?" for unknown types

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/FileTypeIcon.tsx


20. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/SidebarCollapseIcon.tsx ✨ Enhancement +61/-0

Add sidebar control icons

• SVG icon components for sidebar collapse, expand, and add actions
• Reusable icon components with customizable styling

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/SidebarCollapseIcon.tsx


21. workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/NotebookCard.test.tsx 🧪 Tests +151/-0

Add NotebookCard component tests

• Tests for notebook card rendering and interactions
• Coverage for menu toggle, rename, delete, and click actions
• Tests for document count display

workspaces/lightspeed/plugins/lightspeed/src/components/tests/NotebookCard.test.tsx


22. workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/DocumentSidebar.test.tsx 🧪 Tests +142/-0

Add DocumentSidebar component tests

• Tests for document sidebar rendering and state management
• Coverage for collapsed state, document display, and upload progress
• Tests for button interactions and file filtering

workspaces/lightspeed/plugins/lightspeed/src/components/tests/DocumentSidebar.test.tsx


23. workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/OverwriteConfirmModal.test.tsx 🧪 Tests +153/-0

Add OverwriteConfirmModal component tests

• Tests for overwrite confirmation modal rendering and interactions
• Coverage for file list display and button actions
• Tests for modal visibility and close behavior

workspaces/lightspeed/plugins/lightspeed/src/components/tests/OverwriteConfirmModal.test.tsx


24. workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/FileTypeIcon.test.tsx 🧪 Tests +84/-0

Add FileTypeIcon component tests

• Tests for file type icon rendering with various file extensions
• Coverage for color mapping and unknown file types
• Tests for edge cases like multiple dots and hidden files

workspaces/lightspeed/plugins/lightspeed/src/components/tests/FileTypeIcon.test.tsx


25. workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx ✨ Enhancement +106/-19

Integrate notebook view into main chat component

• Added notebook creation and selection state management
• Integrated NotebookView component for active notebook display
• Filtered conversations to exclude notebook-associated conversations
• Added hover effect styling to notebook cards
• Conditionally render chat header only when chat panel is active

workspaces/lightspeed/plugins/lightspeed/src/components/LightSpeedChat.tsx


26. workspaces/lightspeed/plugins/lightspeed/src/translations/ref.ts 📝 Documentation +34/-0

Add English notebook translation keys

• Added 36 new translation keys for notebook UI
• Covers notebook view, upload modal, overwrite modal, and error messages
• Supports file type information and user guidance

workspaces/lightspeed/plugins/lightspeed/src/translations/ref.ts


27. workspaces/lightspeed/plugins/lightspeed/src/translations/ja.ts 📝 Documentation +36/-0

Add Japanese notebook translations

• Added 36 Japanese translations for notebook features
• Includes UI labels, modal titles, error messages, and guidance text

workspaces/lightspeed/plugins/lightspeed/src/translations/ja.ts


28. workspaces/lightspeed/plugins/lightspeed/src/translations/de.ts 📝 Documentation +36/-0

Add German notebook translations

• Added 36 German translations for notebook features
• Covers all notebook UI elements and error messages

workspaces/lightspeed/plugins/lightspeed/src/translations/de.ts


29. workspaces/lightspeed/plugins/lightspeed/src/translations/fr.ts 📝 Documentation +36/-0

Add French notebook translations

• Added 36 French translations for notebook features
• Includes complete UI and error message translations

workspaces/lightspeed/plugins/lightspeed/src/translations/fr.ts


30. workspaces/lightspeed/plugins/lightspeed/src/translations/es.ts 📝 Documentation +36/-0

Add Spanish notebook translations

• Added 36 Spanish translations for notebook features
• Covers all notebook UI elements and error messages

workspaces/lightspeed/plugins/lightspeed/src/translations/es.ts


31. workspaces/lightspeed/plugins/lightspeed/src/translations/it.ts 📝 Documentation +36/-0

Add Italian notebook translations

• Added 36 Italian translations for notebook features
• Includes complete UI and error message translations

workspaces/lightspeed/plugins/lightspeed/src/translations/it.ts


32. workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts ⚙️ Configuration changes +11/-0

Configure notebook query defaults and metadata

• Added configuration reading for notebook model and provider defaults
• Enhanced query request body with model, provider, vector store IDs, and media type
• Preserves existing conversation ID in session metadata

workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts


33. workspaces/lightspeed/.changeset/thin-humans-sparkle.md 📝 Documentation +5/-0

Add changeset for notebook feature release

• Changeset documenting minor version bump for notebook feature additions
• Describes new notebook creation, document upload, and UI components

workspaces/lightspeed/.changeset/thin-humans-sparkle.md


34. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/UploadResourceScreen.tsx ✨ Enhancement +79/-0

New upload resource screen component for notebooks

• New component created to display an upload resource screen with a catalog icon and call-to-action
 button
• Implements Material-UI and PatternFly styling with centered layout and custom icon styling
• Accepts onUploadClick callback prop to handle upload button interactions
• Uses translation hook for internationalized text content

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/UploadResourceScreen.tsx


35. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebooksTab.tsx ✨ Enhancement +11/-1

Add notebook selection and creation callbacks

• Added two new callback props: onSelectNotebook and onCreateNotebook to the component interface
• Wired onCreateNotebook handler to both primary action buttons (in header and empty state)
• Passed onSelectNotebook callback to NotebookCard component for notebook selection handling

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebooksTab.tsx


36. workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/LightspeedChat.test.tsx 🧪 Tests +16/-0

Add notebooks API mocking to test setup

• Added import for notebooksApiRef from the notebooks API module
• Created mockNotebooksApi object with mock implementations for all notebooks API methods (create,
 list, rename, delete, upload, query sessions)
• Registered mockNotebooksApi in the test provider's API configuration

workspaces/lightspeed/plugins/lightspeed/src/components/tests/LightspeedChat.test.tsx


37. workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookCard.tsx ✨ Enhancement +12/-3

Enable notebook card click handling with event propagation control

• Added onClick callback prop to handle notebook card selection
• Made card clickable by adding isClickable prop and onClick handler that invokes the callback
• Added event propagation stoppage in dropdown menu items to prevent triggering card click when
 using rename/delete actions

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookCard.tsx


38. workspaces/lightspeed/plugins/lightspeed/report-alpha.api.md 📝 Documentation +23/-0

Add notebook view translation keys to API documentation

• Added 25 new translation keys for notebook view functionality including title, close, documents
 management, upload modal, and overwrite modal
• Keys cover UI labels, placeholders, error messages, and action buttons for notebook operations
• Extends the lightspeed translation reference with comprehensive notebook-related i18n strings

workspaces/lightspeed/plugins/lightspeed/report-alpha.api.md


Grey Divider

Qodo Logo

@rhdh-qodo-merge

rhdh-qodo-merge Bot commented Apr 13, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (6)   📘 Rule violations (0)   📎 Requirement gaps (0)   🖥 UI issues (0)   🎨 UX Issues (0)
🐞\ ≡ Correctness (4) ☼ Reliability (2)

Grey Divider


Action required

1. Stream reader locked twice 🐞
Description
NotebooksApiClient.querySession() calls response.body.getReader() in the error path and then calls
getReader() again to return a reader, which will throw because the stream is already locked and also
may let non-OK responses proceed without throwing.
Code

workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts[R223-236]

+    if (!response.ok) {
+      const reader = response.body.getReader();
+      const { done, value } = await reader.read();
+      const text = done ? '' : new TextDecoder('utf-8').decode(value);
+      const errorMessage = JSON.parse(text);
+      if (errorMessage?.error) {
+        throw new Error(
+          `failed to query notebook session: ${errorMessage.error}`,
+        );
+      }
+    }
+
+    return response.body.getReader();
+  }
Evidence
The implementation creates a reader in the !ok branch (locking the stream) and then attempts to
create a second reader from the same response.body. Per Web Streams semantics, a ReadableStream can
only be locked to one reader at a time, so the second getReader() will throw; additionally, if the
error payload isn't JSON or lacks .error, the function falls through and tries to return a reader
for an error response.

workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts[205-236]
workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts[223-235]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`NotebooksApiClient.querySession()` locks the response stream by calling `response.body.getReader()` in the error branch and then calls `getReader()` again, which will throw at runtime. It also doesn't reliably throw for non-OK responses.

### Issue Context
This method is used for notebook chat streaming; failed requests should surface a clean error without breaking the stream API.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts[205-236]

### Suggested fix
- If `!response.ok`, read the error via `await response.text()` (or reuse a single reader and `releaseLock()`), then `throw` unconditionally.
- Only call `response.body.getReader()` once (in the success path) and return that reader.
- Wrap JSON parsing of error text in `try/catch` and fall back to raw text when not JSON.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Empty model/provider forced 🐞
Description
The notebooks backend query route always overwrites req.body.model/provider from config and defaults
missing config to empty strings, which violates the system's own non-empty model/provider
requirement and can cause all notebook queries to fail when queryDefaults are not configured.
Code

workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts[R411-414]

+      req.body.model = notebookModel;
+      req.body.provider = notebookProvider;
      req.body.vector_store_ids = [sessionId];
+      req.body.media_type = 'application/json';
Evidence
Router initialization sets notebookModel/notebookProvider to '' when config is absent, and the
query handler unconditionally assigns those to req.body.model and req.body.provider. Elsewhere
in the backend, validateCompletionsRequest enforces model/provider must be non-empty strings,
demonstrating empty strings are considered invalid in this system.

workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts[75-82]
workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts[411-414]
workspaces/lightspeed/plugins/lightspeed-backend/src/service/validation.ts[21-44]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Notebook query requests are forced to include `model` and `provider` values from config, but the code defaults them to empty strings and always overwrites the request body. This creates invalid requests when config is missing.

### Issue Context
The backend already treats empty `model`/`provider` as invalid (`validateCompletionsRequest`). Notebook queries should either:
- fail fast with a clear configuration error, or
- avoid setting these fields unless valid values are present.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts[75-82]
- workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts[411-414]

### Suggested fix
- Change defaults to `undefined` (or use `config.getString(...)` and throw on startup if missing).
- In the handler, only assign `req.body.model/provider` when the configured value is a non-empty string; otherwise return `400/500` with a clear message indicating missing `lightspeed.aiNotebooks.queryDefaults.*`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. DOCX/ODT upload corrupted 🐞
Description
The frontend accepts .docx/.odt and maps them to fileType 'txt', but the backend only supports
parsing txt/md/log as UTF-8 text, so these binary formats will be ingested as garbage content.
Code

workspaces/lightspeed/plugins/lightspeed/src/const.ts[R40-62]

+export const NOTEBOOK_ALLOWED_EXTENSIONS: Record<string, string[]> = {
+  'text/plain': ['.txt', '.log'],
+  'text/markdown': ['.md'],
+  'application/pdf': ['.pdf'],
+  'application/json': ['.json'],
+  'application/x-yaml': ['.yaml', '.yml'],
+  'application/vnd.openxmlformats-officedocument.wordprocessingml.document': [
+    '.docx',
+  ],
+  'application/vnd.oasis.opendocument.text': ['.odt'],
+};
+
+export const NOTEBOOK_EXTENSION_TO_FILE_TYPE: Record<string, string> = {
+  '.txt': 'txt',
+  '.md': 'md',
+  '.pdf': 'pdf',
+  '.json': 'json',
+  '.yaml': 'yaml',
+  '.yml': 'yaml',
+  '.log': 'log',
+  '.docx': 'txt',
+  '.odt': 'txt',
+};
Evidence
UI allowlist includes .docx/.odt and the upload hook derives fileType from extension; both
.docx and .odt map to 'txt'. On the backend, supported file types do not include docx/odt, and
the text parser for txt/md/log is buffer.toString('utf-8'), which will misinterpret binary
documents.

workspaces/lightspeed/plugins/lightspeed/src/const.ts[40-62]
workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useUploadDocument.ts[34-52]
workspaces/lightspeed/plugins/lightspeed-backend/src/service/constant.ts[36-48]
workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/documents/fileParser.ts[41-59]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The UI currently allows `.docx`/`.odt` uploads and maps them to `fileType='txt'`, but the backend parses `txt` as UTF-8 text, corrupting binary document content.

### Issue Context
Backend supported types are `md/txt/pdf/json/yaml/yml/log/url` and text parsing is `buffer.toString('utf-8')`.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/const.ts[40-62]
- workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useUploadDocument.ts[34-52]
- workspaces/lightspeed/plugins/lightspeed-backend/src/service/constant.ts[36-48]
- workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/documents/fileParser.ts[41-59]

### Suggested fix
Choose one:
1) **Disallow docx/odt**: remove `.docx`/`.odt` from `NOTEBOOK_ALLOWED_EXTENSIONS` and `NOTEBOOK_EXTENSION_TO_FILE_TYPE`, and update the upload modal `infoText` translations accordingly.
2) **Add real backend support**: extend `SupportedFileType` and implement docx/odt parsing (e.g., extract text) instead of treating as plain UTF-8 text.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

4. Upload size limit mismatch 🐞
Description
The frontend validates uploads up to 25MB, but the backend enforces a 20MB multer limit, causing
files between 20–25MB to pass UI validation and then fail server-side.
Code

workspaces/lightspeed/plugins/lightspeed/src/const.ts[R36-38]

+export const NOTEBOOK_MAX_FILES = 10;
+export const NOTEBOOK_MAX_FILE_SIZE_BYTES = 25 * 1024 * 1024; // 25 MB
+export const UNTITLED_NOTEBOOK_NAME = 'Untitled Notebook';
Evidence
Frontend uses NOTEBOOK_MAX_FILE_SIZE_BYTES = 25MB for validation while the backend uses
DEFAULT_MAX_FILE_SIZE_MB = 20MB as the multer fileSize limit, so the client-side check is not
aligned with server enforcement.

workspaces/lightspeed/plugins/lightspeed/src/const.ts[36-38]
workspaces/lightspeed/plugins/lightspeed-backend/src/service/constant.ts[27-33]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Client-side validation allows 25MB uploads, but server rejects anything over 20MB.

### Issue Context
Backend multer limit is authoritative; UI should match it to prevent confusing failures.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/const.ts[36-38]
- workspaces/lightspeed/plugins/lightspeed-backend/src/service/constant.ts[27-33]

### Suggested fix
- Either lower `NOTEBOOK_MAX_FILE_SIZE_BYTES` to 20MB, or raise backend multer `DEFAULT_MAX_FILE_SIZE_MB` to 25MB.
- Ensure any user-facing copy (translations) reflects the chosen limit.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Overwrite blocked by max 🐞
Description
validateFiles() rejects uploads when existingCount + files.length exceeds NOTEBOOK_MAX_FILES even if
the files are duplicates that would be overwritten and not increase document count.
Code

workspaces/lightspeed/plugins/lightspeed/src/utils/notebook-upload-utils.ts[R49-59]

+export const validateFiles = (
+  files: File[],
+  existingCount: number = 0,
+): FileValidationResult => {
+  const errors: string[] = [];
+  const valid: File[] = [];
+
+  if (!validateFileCount(existingCount, files.length)) {
+    errors.push('notebook.upload.error.tooManyFiles');
+    return { valid: [], errors };
+  }
Evidence
The count check runs before duplicates are identified; AddDocumentModal passes
existingDocumentNames.length and only later partitions valid into new vs duplicate files. This
means overwriting a file in a full notebook is incorrectly blocked.

workspaces/lightspeed/plugins/lightspeed/src/utils/notebook-upload-utils.ts[49-59]
workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/AddDocumentModal.tsx[95-113]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The max-files validation counts all dropped files even if some are duplicates that would overwrite existing documents.

### Issue Context
`AddDocumentModal` determines duplicates after calling `validateFiles`, so `validateFiles` cannot currently account for overwrites.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/utils/notebook-upload-utils.ts[49-59]
- workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/AddDocumentModal.tsx[95-113]

### Suggested fix
- Move the file-count validation to after duplicate detection in `AddDocumentModal` and validate only `newFiles.length`, OR
- Extend `validateFiles` to accept existing names (or a duplicate predicate) so it can compute `netNewCount` and validate `existingCount + netNewCount`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


6. Completed uploads never removed 🐞
Description
NotebookView removes failed/cancelled uploads from state but never removes completed uploads from
pendingUploads/uploadingFileNames, causing unbounded state growth and relying on indirect filtering
to hide completed entries.
Code

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookView.tsx[R386-417]

+    for (const result of completedOrFailed) {
+      processedIds.current.add(result.documentId);
+      if (result.status !== 'completed') {
+        idsToRemove.add(result.documentId);
+        namesToRemove.add(result.fileName);
+      } else {
+        newCompletedNames.add(result.fileName);
+      }
+
+      if (result.status === 'completed') {
+        newAlerts.push({
+          key: Date.now() + result.documentId,
+          title: (t as Function)('notebook.upload.success', {
+            fileName: result.fileName,
+          }) as string,
+          variant: 'success',
+        });
+      } else {
+        newAlerts.push({
+          key: Date.now() + result.documentId,
+          title: (t as Function)('notebook.upload.failed', {
+            fileName: result.fileName,
+          }) as string,
+          variant: 'danger',
+        });
+      }
+    }
+
+    setPendingUploads(prev => prev.filter(u => !idsToRemove.has(u.documentId)));
+    setUploadingFileNames(prev =>
+      prev.filter(name => !namesToRemove.has(name)),
+    );
Evidence
In the polling effect, only non-completed results add entries to idsToRemove/namesToRemove, and
the state updates remove only those. Completed uploads are only added to completedFileNames,
leaving pendingUploads and uploadingFileNames to grow over time.

workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookView.tsx[369-417]
workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookView.tsx[431-431]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Successful uploads are never removed from `pendingUploads` / `uploadingFileNames`, which can grow without bound and can keep `hasDocuments` true even when documents are not present.

### Issue Context
The UI currently hides spinners via `completedFileNames`, but the underlying arrays still retain completed entries.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/components/notebooks/NotebookView.tsx[369-425]

### Suggested fix
- For `status === 'completed'`, also add `documentId` to `idsToRemove` and `fileName` to `namesToRemove`, then remove them from `pendingUploads`/`uploadingFileNames` just like failed/cancelled.
- Optionally clear `completedFileNames` entries once the document list refresh includes the uploaded document.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +223 to +236
if (!response.ok) {
const reader = response.body.getReader();
const { done, value } = await reader.read();
const text = done ? '' : new TextDecoder('utf-8').decode(value);
const errorMessage = JSON.parse(text);
if (errorMessage?.error) {
throw new Error(
`failed to query notebook session: ${errorMessage.error}`,
);
}
}

return response.body.getReader();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. Stream reader locked twice 🐞 Bug ≡ Correctness

NotebooksApiClient.querySession() calls response.body.getReader() in the error path and then calls
getReader() again to return a reader, which will throw because the stream is already locked and also
may let non-OK responses proceed without throwing.
Agent Prompt
### Issue description
`NotebooksApiClient.querySession()` locks the response stream by calling `response.body.getReader()` in the error branch and then calls `getReader()` again, which will throw at runtime. It also doesn't reliably throw for non-OK responses.

### Issue Context
This method is used for notebook chat streaming; failed requests should surface a clean error without breaking the stream API.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/api/NotebooksApiClient.ts[205-236]

### Suggested fix
- If `!response.ok`, read the error via `await response.text()` (or reuse a single reader and `releaseLock()`), then `throw` unconditionally.
- Only call `response.body.getReader()` once (in the success path) and return that reader.
- Wrap JSON parsing of error text in `try/catch` and fall back to raw text when not JSON.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +40 to +62
export const NOTEBOOK_ALLOWED_EXTENSIONS: Record<string, string[]> = {
'text/plain': ['.txt', '.log'],
'text/markdown': ['.md'],
'application/pdf': ['.pdf'],
'application/json': ['.json'],
'application/x-yaml': ['.yaml', '.yml'],
'application/vnd.openxmlformats-officedocument.wordprocessingml.document': [
'.docx',
],
'application/vnd.oasis.opendocument.text': ['.odt'],
};

export const NOTEBOOK_EXTENSION_TO_FILE_TYPE: Record<string, string> = {
'.txt': 'txt',
'.md': 'md',
'.pdf': 'pdf',
'.json': 'json',
'.yaml': 'yaml',
'.yml': 'yaml',
'.log': 'log',
'.docx': 'txt',
'.odt': 'txt',
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. Docx/odt upload corrupted 🐞 Bug ≡ Correctness

The frontend accepts .docx/.odt and maps them to fileType 'txt', but the backend only supports
parsing txt/md/log as UTF-8 text, so these binary formats will be ingested as garbage content.
Agent Prompt
### Issue description
The UI currently allows `.docx`/`.odt` uploads and maps them to `fileType='txt'`, but the backend parses `txt` as UTF-8 text, corrupting binary document content.

### Issue Context
Backend supported types are `md/txt/pdf/json/yaml/yml/log/url` and text parsing is `buffer.toString('utf-8')`.

### Fix Focus Areas
- workspaces/lightspeed/plugins/lightspeed/src/const.ts[40-62]
- workspaces/lightspeed/plugins/lightspeed/src/hooks/notebooks/useUploadDocument.ts[34-52]
- workspaces/lightspeed/plugins/lightspeed-backend/src/service/constant.ts[36-48]
- workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/documents/fileParser.ts[41-59]

### Suggested fix
Choose one:
1) **Disallow docx/odt**: remove `.docx`/`.odt` from `NOTEBOOK_ALLOWED_EXTENSIONS` and `NOTEBOOK_EXTENSION_TO_FILE_TYPE`, and update the upload modal `infoText` translations accordingly.
2) **Add real backend support**: extend `SupportedFileType` and implement docx/odt parsing (e.g., extract text) instead of treating as plain UTF-8 text.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

config.getOptionalString(
'lightspeed.aiNotebooks.queryDefaults.provider_id',
) ?? '';

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@JslYoon You were not reading the default models so I have added these code, let me know it looks good to you, or I can remove it.

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
@Jdubrick
Jdubrick requested a review from JslYoon April 17, 2026 13:30
@ShiranHi

Copy link
Copy Markdown

@its-mitesh-kumar could you add some screenshots to this PR once they are ready? You can use this prototype as a reference to ensure the implementation matches the design.

@rhdh-gh-app

rhdh-gh-app Bot commented Apr 24, 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-lightspeed-backend workspaces/lightspeed/plugins/lightspeed-backend patch v2.2.1
@red-hat-developer-hub/backstage-plugin-lightspeed workspaces/lightspeed/plugins/lightspeed minor v2.2.1

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
buffer += chunk.toString();
const lines = buffer.split('\n');
buffer = buffer.endsWith('\n') ? '' : lines.pop() || '';
const blocks = buffer.split('\n\n');

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@JslYoon Please see if this changes looks good to you.
Notebook chat streaming: normalize SSE format to match chat tab

The notebook query endpoint proxies responses from Lightspeed Core, which uses the Responses API SSE format (event: response.output_text.delta / data: {...}). However, the frontend useConversationMessages hook expects the legacy streaming format (data: {"event": "token", "data": {"token": "..."}}), which is what the chat tab already uses.

Without this transform, the frontend received the entire response as a single blob instead of streaming token-by-token, because it couldn't parse the incoming SSE events.

Added a createResponsesApiTransform in notebooksRouters.ts that converts Responses API SSE events to the legacy format on the fly, so both chat and notebook tabs stream identically. The transform also captures the conversation_id from the first response.created event and persists it on the session.

@JslYoon JslYoon Apr 27, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

That's fine by me.

@its-mitesh-kumar its-mitesh-kumar changed the title Feat/lightspeed notebook chat feat(lightspeed): notebook chat Apr 24, 2026
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

@JslYoon As already informed Notebook document upload shows failure status despite successful upload; document-based Q&A not working. I have created the bug for the same. Please have a look. https://redhat.atlassian.net/browse/RHDHBUGS-3015

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

@ciiay ciiay 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.

Hi @its-mitesh-kumar , I tested locally and I had one concern. When I tried to upload 00001.log file, it failed for the first time I uploaded it, then I tried again. The second time it showed up in the file list but still I got another failed message in the alert model. Please refer the screenshot and the backend log I attached.

Image Image
2026-04-27T03:15:42.130Z lightspeed error /v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents/00001.log/status: Document not found: 00001.log Document not found: 00001.log cause=undefined name="NotFoundError" stack="NotFoundError: Document not found: 00001.log\n    at DocumentService.getFileStatus (/Users/yicai/redhat/rhdh-plugins/workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/documents/documentService.ts:222:13)\n    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)\n    at async <anonymous> (/Users/yicai/redhat/rhdh-plugins/workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts:406:26)\n    at async <anonymous> (/Users/yicai/redhat/rhdh-plugins/workspaces/lightspeed/plugins/lightspeed-backend/src/service/notebooks/notebooksRouters.ts:150:9)"
2026-04-27T03:15:42.132Z rootHttpRouter info [2026-04-27T03:15:42.132Z] "GET /api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents/00001.log/status HTTP/1.1" 404 67 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" type="incomingRequest" date="2026-04-27T03:15:42.132Z" method="GET" url="/api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents/00001.log/status" status=404 httpVersion="1.1" userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" contentLength=67 referrer="http://localhost:3000/"
2026-04-27T03:15:42.144Z lightspeed info Document "00001.log" (ID: 00001.log) upload started with file file-e90b0c9c42014317928e1401d00f4d11 
2026-04-27T03:15:42.144Z lightspeed info Background upload succeeded: 00001.log 
2026-04-27T03:15:43.178Z rootHttpRouter info [2026-04-27T03:15:43.178Z] "GET /api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents/00001.log/status HTTP/1.1" 200 113 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" type="incomingRequest" date="2026-04-27T03:15:43.178Z" method="GET" url="/api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents/00001.log/status" status=200 httpVersion="1.1" userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" contentLength=113 referrer="http://localhost:3000/"
2026-04-27T03:16:10.825Z lightspeed info Parsing file 00001.log for fileType log 
2026-04-27T03:16:10.845Z lightspeed info File created - id: file-1040ad3ed157440f8db2c5396fec332d, filename: 00001.log 
2026-04-27T03:16:10.846Z rootHttpRouter info [2026-04-27T03:16:10.846Z] "PUT /api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents HTTP/1.1" 202 157 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" type="incomingRequest" date="2026-04-27T03:16:10.846Z" method="PUT" url="/api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents" status=202 httpVersion="1.1" userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" contentLength=157 referrer="http://localhost:3000/"
2026-04-27T03:16:10.941Z lightspeed info Deleting document 00001.log from vs_ecbc8901-b073-4169-9256-4bef7a9228d0 
2026-04-27T03:16:11.045Z lightspeed info Listing documents for session vs_ecbc8901-b073-4169-9256-4bef7a9228d0 
2026-04-27T03:16:11.077Z rootHttpRouter info [2026-04-27T03:16:11.077Z] "GET /api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents/00001.log/status HTTP/1.1" 304 0 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" type="incomingRequest" date="2026-04-27T03:16:11.077Z" method="GET" url="/api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents/00001.log/status" status=304 httpVersion="1.1" userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" referrer="http://localhost:3000/"
2026-04-27T03:16:11.107Z lightspeed info Found 2 documents in session vs_ecbc8901-b073-4169-9256-4bef7a9228d0 
2026-04-27T03:16:11.108Z rootHttpRouter info [2026-04-27T03:16:11.108Z] "GET /api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents HTTP/1.1" 200 459 "http://localhost:3000/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" type="incomingRequest" date="2026-04-27T03:16:11.108Z" method="GET" url="/api/lightspeed/ai-notebooks/v1/sessions/vs_ecbc8901-b073-4169-9256-4bef7a9228d0/documents" status=200 httpVersion="1.1" userAgent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/146.0.0.0 Safari/537.36" contentLength=459 referrer="http://localhost:3000/"
2026-04-27T03:16:11.184Z lightspeed info Deleted document 00001.log (file file-e90b0c9c42014317928e1401d00f4d11) from session vs_ecbc8901-b073-4169-9256-4bef7a9228d0 
2026-04-27T03:16:11.250Z lightspeed info Document "00001.log" (ID: 00001.log) upload started with file file-1040ad3ed157440f8db2c5396fec332d 
2026-04-27T03:16:11.250Z lightspeed info Background upload succeeded: 00001.log 

@its-mitesh-kumar

its-mitesh-kumar commented Apr 27, 2026

Copy link
Copy Markdown
Member Author

@ciiay I have already created the bug for document upload status api is not giving proper response. It need to be fixed from the backend.

@JslYoon As already informed Notebook document upload shows failure status despite successful upload; document-based Q&A not working. I have created the bug for the same. Please have a look. https://redhat.atlassian.net/browse/RHDHBUGS-3015

@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

@its-mitesh-kumar could you add some screenshots to this PR once they are ready? You can use this prototype as a reference to ensure the implementation matches the design.

@ShiranHi Screenrecording has been updated in the PR description.

@ShiranHi

Copy link
Copy Markdown

@ShiranHi Screenrecording has been updated in the PR description.

Thank you @its-mitesh-kumar , it looks great. We only need to add a confirmation modal when deleting a resource (Figma).

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

@karthikjeeyar karthikjeeyar 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.

Overall looks great.

Just few small observation during testing.

New route needed for notebook conversation

  • Every notebook chat should have its own Route and refresh should stay on the same details page

Comment on lines 522 to 523

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.

Notebook content area is not full-width when the sidebar is not collapsed. I think this should be full width matching the below message bar's width.

Image

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@karthikjeeyar Tried improving the spacing. Take a pull and see.

Screen.Recording.2026-04-27.at.8.20.10.PM.mov

@karthikjeeyar

Copy link
Copy Markdown
Member

Lightspeed chat has "Attach" button
Screenshot 2026-04-27 at 7 58 01 PM

Notebooks doesn't have that "Attach" button. For consistency can we add that here too? I can see attach button is added in the figma too, but I am not sure if this was removed after discussion with UX later.

Screenshot 2026-04-27 at 7 57 53 PM

@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

Lightspeed chat has "Attach" button
Notebooks doesn't have that "Attach" button. For consistency can we add that here too? I can see attach button is added in the figma too, but I am not sure if this was removed after discussion with UX later.

@ShiranHi Should I add back the attach file icon ?

@ShiranHi

Copy link
Copy Markdown

Lightspeed chat has "Attach" button
Notebooks doesn't have that "Attach" button. For consistency can we add that here too? I can see attach button is added in the figma too, but I am not sure if this was removed after discussion with UX later.

@ShiranHi Should I add back the attach file icon ?

I’d prefer not to include it as it isn't reflected in the existing Figma files. Let's keep it simple for now.

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

its-mitesh-kumar commented Apr 27, 2026

Copy link
Copy Markdown
Member Author

New route needed for notebook conversation

@karthikjeeyar I have already Bug for the same is here : https://redhat.atlassian.net/browse/RHDHBUGS-2986

@karthikjeeyar

karthikjeeyar commented Apr 27, 2026

Copy link
Copy Markdown
Member

Notebook's conversation showing the source as external link and clicking on it doesn't do anything:

image

For lightspeed use-case, the docs_url was always an external url, but for notebooks these sources are internal documents and docs_url is usually set to null.

So please modify this line where it sets isExternal variable (always sets to true) to conditionally set true or false based on the availability of docs_url variable

The above suggestion will remove the external icon in this source link:

image

cc: @ShiranHi

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

its-mitesh-kumar commented Apr 27, 2026

Copy link
Copy Markdown
Member Author

Suggestion will remove the external icon in this source link:

@karthikjeeyar Addressed.

  1. Notebook Chat
Screenshot 2026-04-27 at 10 05 23 PM 2. Lightspeed Chat Screenshot 2026-04-27 at 10 05 53 PM

@sonarqubecloud

Copy link
Copy Markdown

@JslYoon

JslYoon commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

All problems mentioned will be fixed in the following PRs @its-mitesh-kumar :
#2861
#2928

@karthikjeeyar karthikjeeyar 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.

/approve
/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Apr 28, 2026
@karthikjeeyar
karthikjeeyar merged commit d9df5b8 into redhat-developer:main Apr 28, 2026
12 checks passed
lokanandaprabhu pushed a commit to lokanandaprabhu/rhdh-plugins that referenced this pull request May 14, 2026
* feat(lightspeed): create notebook flow

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

* feat(lightspeed): creating new notebook

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

* updating status of documents

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

* updating the unit tests

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

* handling overwrite in create flow

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

* adding changeset

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

* feat(lightspeed): adding chat

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

* delete of document

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

* formatting the query response

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

* adding changeset

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

* updating delete functionality

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

* fixing width

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

* improving spacing

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

* update doc_url

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

---------

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
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.

5 participants