Skip to content

[ZEPPELIN-6748] Assemble the fixture-backed Assistant conversation panel - #5578

Open
miinhho wants to merge 10 commits into
apache:masterfrom
miinhho:ZEPPELIN-6748-fixture-panel
Open

miinhho wants to merge 10 commits into
apache:masterfrom
miinhho:ZEPPELIN-6748-fixture-panel

Conversation

@miinhho

@miinhho miinhho commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

What is this PR for?

Assemble the existing Assistant components into a fixture-backed conversation panel, available in Storybook and in notebooks with ?reactAssistant=true.

The panel supports:

  • Creating conversations on the first send, selecting saved conversations, and confirming deletion.
  • Streaming answers with Markdown and tool activity, followed by history reconciliation.
  • Keeping each conversation’s draft and running answer separate when switching conversations.
  • Loading earlier history while preserving message identity and the reader’s scroll position.
  • Presenting creation, send, run, and history-loading failures through the existing error components.

Conversation state, run-event accumulation, history reconciliation, and React subscription have separate owners. The fixture accepts explicit seed data, a reference clock, and failure scenarios independently of Storybook.

What type of PR is it?

Feature

What is the Jira issue?

How should this be tested?

Unit and component tests

From zeppelin-web-angular/projects/zeppelin-react:

npm test -- \
src/pages/assistant-workspace \
src/entities/assistant/ui/AssistantAnswer.spec.tsx \
--maxWorkers=1 --no-file-parallelism

npm run typecheck
npm run lint

These tests cover run-event handling, conversation switching, stale responses, history reconciliation, fixture behavior, deletion confirmation, and answer rendering across state transitions.

Notebook E2E tests

Start the Zeppelin backend on localhost:8080, then run from zeppelin-web-angular:

npm run e2e -- e2e/tests/notebook/assistant

The conversation scenarios check:

  • Streaming a new answer, preserving its DOM through completion, and restoring saved history.
  • Switching away from an active conversation without mixing drafts or results.
  • Loading earlier history and joining a split answer without replacing the later answer.

Manual verification

  1. Open a notebook with ?reactAssistant=true and open the Assistant sidebar.
  2. Send a question and observe the streaming answer, tool activity, and completed Markdown table.
  3. Send in one conversation, switch to another, and return to verify that the draft and answer remain associated with the correct conversation.
  4. Open Revenue analysis and scroll to the top to load earlier messages.
  5. Use the panel stories to exercise creation failure, rejected sends, unknown acceptance, and accepted-run failure.

To open the stories, run from zeppelin-web-angular/projects/zeppelin-react:

npm run storybook

Open Assistant / ConversationPanel.

Screenshots (if appropriate)

Screenshot 2026-10-21 101119

Questions:

  • Does the license files need to update? No.
  • Is there breaking changes for older versions? No.
  • Does this needs documentation? No.

@miinhho
miinhho force-pushed the ZEPPELIN-6748-fixture-panel branch from 631f77b to 1b6333d Compare October 21, 2026 08:13
@miinhho
miinhho marked this pull request as ready for review October 21, 2026 08:13
@voidmatcha

Copy link
Copy Markdown
Member

Could you please check these two cases?

  1. If a question is rejected before acceptance while the initial history is loading, the conversation remains blank. Reloading the history while preserving the error and question would help.
  2. After receiving an answer in an existing conversation, its timestamp and position in the conversation list remain unchanged. Refreshing the list after an accepted run finishes would address this.

I’ve prepared suggested fixes and regression tests for reference only.

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

If a question is sent before the initial history finishes loading, a pagination boundary case can cause the previous failed answer to appear above its original question when the next message is sent.

reproduction-plain.mp4

Would it make sense to disable sending until the initial history has loaded successfully? Could you also check whether this belongs in this PR or should be handled in ZEPPELIN-6749? This is a non-blocking comment, as it does not reproduce with the current fixture.

The recording uses the PR’s model and message renderer connected to a real Zeppelin server, with locally controlled LLM responses.

@miinhho

miinhho commented Oct 25, 2026

Copy link
Copy Markdown
Contributor Author

If a question is sent before the initial history finishes loading, a pagination boundary case can cause the previous failed answer to appear above its original question when the next message is sent.

reproduction-plain.mp4
Would it make sense to disable sending until the initial history has loaded successfully? Could you also check whether this belongs in this PR or should be handled in ZEPPELIN-6749? This is a non-blocking comment, as it does not reproduce with the current fixture.

The recording uses the PR’s model and message renderer connected to a real Zeppelin server, with locally controlled LLM responses.

This is not an issue with the server returning history in the wrong order. It is a boundary case in the current panel model, which allows sending before the initial history request finishes.

If a question is sent before the initial history loads, the run can fail. The subsequent history request can return only the answer, with the question on the previous page. On the next send, the model moves the failed answer into the message list and places it before its question. I reproduced this by supplying those page responses through the existing REST adapter to the current model.

Following your suggestion, can we allow sending in an existing conversation only after the latest history page loads successfully once? Users can still edit their draft, the unsent question, while history loads, but they cannot submit it. If loading fails, the panel keeps the draft and offers a retry for the history request. I propose enforcing this condition in both the UI and the model’s send method.

The first send in a new local conversation will remain available. This restriction will not apply to later history reloads or requests for older pages after the initial load succeeds.

This approach defines when sending is allowed, rather than adding more history reconciliation logic to handle this case. Can we apply this policy in this PR and make sure that the same rule works with a real server in ZEPPELIN-6749?

voidmatcha
voidmatcha previously approved these changes Oct 25, 2026

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

I agree with the proposed approach. (My approval means I have no further comments on the rest of the changes; please go ahead and apply the proposed fix)

Applying the initial-history send guard in both the UI and the model in this PR, then verifying it against a real server in ZEPPELIN-6749, makes sense. I've added the corresponding verification criteria to ZEPPELIN-6749 and ZEPPELIN-6750.

@voidmatcha voidmatcha 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 👍

Just noting for future reference that submittedQuestion may be useful for follow-up work such as ZEPPELIN-6755.

This branch has not been deployed

No deployments
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