Render Duo clarifying questions as an interactive card in work item discussions

Summary

When the workplan flow needs a human decision it posts the question as a resolvable discussion on the work item. Today that renders as plain prose, so answering means reading it, working out what the options were, and typing a reply.

This renders the question as a card: the question, the options the agent considered, and which one it recommends. Choosing one posts the answer as a reply and resolves the thread.

Resolving is the part that matters. Discussions::ResolveService publishes WorkItems::DiscussionResolvedEvent, and once every question the run posted is resolved, ContinueWorkplanAfterDiscussionsResolvedWorker resumes that same paused workflow with the replies. The flow keeps its conversation history rather than starting over.

Implementation notes

  • New EE component ee/app/assets/javascripts/work_items/components/notes/duo_question_note.vue
  • CE no-op stub at the same path under app/, imported through ee_else_ce so FOSS renders nothing
  • Mount in app/assets/javascripts/work_items/components/notes/work_item_note.vue, gated on isFirstNote && !isDiscussionResolved
  • Answering posts a reply via the existing createWorkItemNote mutation and resolves via toggleWorkItemNoteResolveDiscussion, both already exist in CE
  • Hide the raw payload with pre[data-lang-params='duo-question'] { display: none } in page_bundles/work_items.scss, so it never flashes before hydration and stays hidden if the bundle never runs

Gated on two existing feature flags, both off by default: workplan (whether the Workplan widget exists at all) and duo_workplan_async_flow (whether generation runs as a background flow). No new flag is introduced. Nothing renders unless both are on and a note actually contains a question payload.

Proposed Designs

Complete prototypes available here

Questions waiting for User Input Questions with accepted answer Custom Response
Light image image image
Dark image image image

Acceptance criteria

  • Card renders the question, its options, and a Recommended badge where the agent expressed a preference
  • Answering posts a reply and resolves the discussion
  • Renders nothing in FOSS
  • A malformed or absent payload results in no card, never an error
  • Jest specs for rendering, answering, and the malformed case

Depends on

Blocked by the payload parser.

Reference

Working implementation on branch kp-sdd-hitl-poc: !248609 (closed)

Edited by Kushal Pandya