feat(expert): grouped clarifying questions UI + render robustness (#407)#7556
feat(expert): grouped clarifying questions UI + render robustness (#407)#7556andypalmi wants to merge 7 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7556 +/- ##
=======================================
Coverage 76.47% 76.47%
=======================================
Files 413 413
Lines 21775 21775
Branches 5736 5736
=======================================
Hits 16652 16652
Misses 5123 5123
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…crash Add an ErrorBoundary and wrap each answer item in it, so a failure in one section degrades only that section instead of blanking the whole message. Also guard the optional streamable chain in StandardResourceCard that could throw on a null value and take down the message.
) The Expert can ask 1-4 clarifying questions in a single turn, each rendered as its own single- or multi-select option card; all answers are collected before the turn is submitted. Answered cards can be edited and resubmitted, and a card from a past turn is disabled once a newer message arrives. Adds a follow-up-questions cadence setting (all at once vs one at a time) in the composer settings menu, shipped to the agent via the expert context.
7ee8af7 to
213b352
Compare
- Guard the optional streamable chain in FlowResourceCard directly instead of relying on a render boundary to mask the throw. Reduce ErrorBoundary to a single last-resort backstop per answer item in AiMessage; drop the per-section boundary wrappers in AnswerWrapper. - Rewrite QuestionsList on top of the existing ff-radio-group (single-select) and ff-checkbox (multi-select) components so options look like standard, clickable form controls and stay consistent with the rest of the app. - Replace the imperative growComposerToContent DOM measuring with CSS field-sizing on the textarea; drop the manual reflows and the auto-grown flag. The composer auto-sizes to content and pins to an explicit height only after a drag-resize.
Per review: the local-catch pattern was the only one in the frontend; the rest of the app leans on the global app.config.errorHandler. The real throws are now guarded at their source (the optional streamable chains in the resource cards), so the boundary was redundant. Remove it entirely and let genuinely unexpected render errors surface through the global handler like everywhere else.
Replace the composer kebab menu with a settings gear that opens an ff-dialog. The follow-up-questions cadence control now lives in the dialog as an ff-radio-group, with a FormHeading per section so the panel can grow as more settings are added.
|
Hey so while testing this - I am running into an issue where once I submit my answers, the chat just times out. This is on https://7556.flowfuse.dev/. I get no console errors. Example messages, I've been able to recreate this multiple times - https://gist.github.com/n-lark/87be54af4c32064ff7223190a8545056
|
|
@n-lark Unfortunately that's an issue with the Posthog feature flags to have the staging environment point to the dev agent and unrelated to this branch EDIT: actually, let me look a bit more into this because I also got the AIMessage back but it did not render |
handleMessageResponse lived in the composer's send handler, so a reply to a query sent from the questions card was fetched but never rendered over HTTP (without comms-beta the reply only renders via the MQTT push handler). Fold the response handling into handleQuery so every entry point (composer and the question/plan cards) renders the reply without re-implementing it.
|
@n-lark this should now be fixed. Root cause: rendering the reply lived in the composer's send handler, so a reply to a query submitted from the clarifying-questions card was fetched but never rendered when comms-beta (MQTT) is off and the chat falls back to HTTP. The response handling now lives in the shared handleQuery action, so every entry point (composer and the question/plan cards) renders the reply. It only surfaced where the MQTT push path is unavailable, which is why staging is hitting it right now. I will test this myself once it lands in the staging environment, and you are welcome to give it another go too. Let me know if you still see it. |
|
@n-lark I can confirm it's working over HTTP now. |


Summary
Frontend for the Expert "ask before acting" clarifying-questions UX (FlowFuse/product#407), plus a couple of robustness fixes in the answer rendering.
Grouped clarifying questions: the Expert can ask 1-4 questions in a single turn, each rendered as its own option group (single- or multi-select), and all answers are collected before the turn is submitted. Answered questions can be edited and resubmitted; the card is disabled once a newer message arrives so a stale turn can't be answered. The options are built on the existing form components (
ff-radio-groupfor single-select,ff-checkboxfor multi-select) so they look and behave like the rest of the app.Cadence control: a follow-up-questions setting in the composer menu (all at once vs one at a time), shipped to the agent via the expert context.
Composer auto-size: the chat input grows with its content (typed text, or an edited question loaded back in) using CSS
field-sizing: contentcapped by a max-height, and only pins to a fixed height once the user drag-resizes it.Resource card robustness: guarded the optional
streamablechains inStandardResourceCardandFlowResourceCardthat could throw on a null/malformed value and blank the whole message. They now degrade to "nothing to show" for that field instead, and the streaming list still advances.Testing
npm run lint,npm run buildandnpm run test:unit:frontend(570 tests) all pass.Manual: grouped questions render and collect answers; a single missing value renders as a single question; cadence setting persists; composer grows with loaded/edited content.
Relates to FlowFuse/product#407