Skip to content

[ZEPPELIN-6746] Add AI Assistant question composer component - #5569

Open
kimyenac wants to merge 5 commits into
apache:branch-voidmatcha-assistant-storybook-tempfrom
kimyenac:ZEPPELIN-6746
Open

kimyenac wants to merge 5 commits into
apache:branch-voidmatcha-assistant-storybook-tempfrom
kimyenac:ZEPPELIN-6746

Conversation

@kimyenac

@kimyenac kimyenac commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

What is this PR for?

Add the AI Assistant question composer: a controlled component that takes a value, change and submit callbacks, and read-only and sending states. Nothing is sent anywhere. The parent receives the question and decides what to do with it. The component lives in projects/zeppelin-react/src/entities/assistant/ui.

Base: branch-voidmatcha-assistant-storybook-temp (branched at 4599ad2d9). This PR adds only the commits below, as four new files. The base already contains the prerequisite PRs: ZEPPELIN-6740 (#5562, Storybook) and ZEPPELIN-6743 (#5565). Once those merge, the base goes back to master.

Commits:

  1. Question composer
    • AssistantComposer is a <form> with an antd Input.TextArea (auto-sizing, 2–8 rows) and a Send Button.
    • The value is controlled. onSubmit receives the question with surrounding whitespace trimmed. Clearing the input afterwards is left to the parent, so it can keep the text if sending fails.
    • Nothing is submitted, by the button, Enter or the form, when:
      • the input is empty or whitespace only (the server rejects a blank prompt with 400),
      • readOnly is set (for example a conversation owned by another user). The textarea is disabled and a note explains why (readOnlyReason, with a default).
      • sending is set (the server accepts one run per conversation). The textarea becomes read-only, so the question stays visible, and the button shows a spinner.
    • Enter sends and Shift+Enter adds a new line. An Enter that confirms an IME composition (Korean, Japanese, …) does not send. Otherwise the last syllable of a Korean question would send it. Commit 3 extends this to Safari.
  2. Stories
    • Assistant/Composer: Empty, Draft, WhitespaceOnly, Sending, ReadOnly.
    • Assistant/Composer/Playground keeps its own value: type, send with the button or Enter, see onSubmit in the Actions panel and the input cleared.
  3. Review: do not send on the Enter that confirms an IME composition in Safari (by @voidmatcha)
    • Safari fires compositionend before that Enter, so it arrives with isComposing: false and keyCode: 229. The check now covers both.
  4. Review: pin the controlled value of the composer in tests (by @voidmatcha)
    • The field keeps showing the parent's value when onChange is ignored, and shows and sends a value the parent sets later. Both tests fail if value becomes defaultValue.
  5. Review: raise the composer placeholder contrast
    • antd's placeholder colour was about 1.8:1 (light) and 2.3:1 (dark). It now uses the theme's textTertiary, which the theme lifts to 4.5:1. Measured in Storybook: 6.10:1 / 6.39:1 on the panel, 5.84:1 on the read-only field.

Styling uses @vanilla-extract/css through the Assistant theme contract only. The field draws a single focus ring for the textarea inside it. The HTML/CSS screens in voidmatcha/assistant-storybook-share were used as a design reference. The code is written from scratch.

Out of scope (per the issue): per-conversation draft persistence, actual sending, Stop and retry. These belong to panel assembly (ZEPPELIN-6748) or follow-up issues.

What type of PR is it?

Feature

Todos

  • - Task

What is the Jira issue?

How should this be tested?

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

  • npm ci, npm test (138 passed, 8 new), npm run typecheck, npm run lint and npm run build:storybook all pass.
    • typecheck needs npm ci in zeppelin-web-angular first, because the SDK resolves rxjs from there.
    • The new files also pass the frontend's prettier --check.
  • npm run storybook: every story above checked in both themes, including typing Korean and pressing Enter mid-composition in Playground (Chrome). Safari was not tried; commit 3 is covered by a keyCode: 229 unit test.
  • The spec was mutation-checked: dropping the IME check, the Safari keyCode check, the trim, the sending guard, the read-only guard or the read-only textarea while sending, or using defaultValue, each fails the intended test.
  • npm run test:storybook -- --workers=1: all 14 tests pass. With the default 3 workers the existing python3 -m http.server web server occasionally drops requests. The base's own story reproduces this, so it is not caused by these stories (see [ZEPPELIN-6745] Add AI Assistant message and answer state UI #5567).

Screenshots (if appropriate)

See the Assistant/Composer stories.

Questions:

  • Does the license files need to update? No. There are no new dependencies.
  • Is there breaking changes for older versions? No. Only new files are added.
  • Does this needs documentation? No.

@voidmatcha
voidmatcha changed the base branch from master to branch-voidmatcha-assistant-storybook-temp October 13, 2026 07:42

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

Thanks. I went through the Storybook stories (Empty, Draft, WhitespaceOnly, Sending, ReadOnly, Playground) in both themes, and the guards, trimming, and read-only/sending states are implemented as described. Two small things below; the changes are on my branch: voidmatcha/zeppelin@9f25deb...ZEPPELIN-6746-pr5569-review-fixes

Please take whatever you find useful.

Minor, not blocking: the placeholder text ("Ask about this notebook") uses antd's default color, whose contrast against the background is about 1.8:1 in light and 2.3:1 in dark, below the 4.5:1 WCAG AA minimum for normal text. Could be a follow-up.

@kimyenac

Copy link
Copy Markdown
Contributor Author

Thanks for the review and for the fixes. I took all three:

  • Safari IME Enter (3682a7c, your commit as is): removing the keyCode === 229 check fails the IME test, as you said. I could not try real Safari either. That is noted in the PR body.
  • Controlled value tests (05f40d3, your commit as is): switching value to defaultValue fails both new tests here too.
  • Placeholder contrast (5dfbbb1): the placeholder now uses the theme's textTertiary, which the theme already lifts to 4.5:1. That is the same color as the "Shift + Enter" hint. Measured in Storybook: 6.10:1 (light) and 6.39:1 (dark) on the panel, and 5.84:1 on the read-only field.

npm test (138 passed), typecheck, lint, build:storybook and test:storybook --workers=1 pass. The PR body is updated.

@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 confirmed the suggested changes are all in (Safari IME, the value test, and placeholder contrast).

LGTM 👍 Once the prerequisite PRs merge, I will retarget this PR to master and check the final diff and CI before merging.

@voidmatcha

Copy link
Copy Markdown
Member

@kimyenac #5562 is on master, and this PR doesn't need #5561 or #5565. Could you rebase onto master, force-push, and then switch the base to master?

git fetch https://github.com/apache/zeppelin.git master
git rebase --onto FETCH_HEAD 4599ad2d9
git push --force-with-lease

It rebases without conflicts and the tests pass. Please also drop the "Blocked by" line from the description.

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