Studio Code: unblock multi-question prompts with a user reply - #4689
Studio Code: unblock multi-question prompts with a user reply#4689gcsecsey wants to merge 5 commits into
Conversation
…uestion-prompts-in-classic-studio-code-ui-v1 # Conflicts: # apps/studio/src/components/studio-code-session/index.tsx # apps/ui/src/ui-classic/components/session-view/index.tsx
… and a nonexistent emitProgress export
There was a problem hiding this comment.
Pull request overview
This PR updates Studio Code’s chat runtimes (Classic UI, Agentic UI, and CLI tool progress) to prevent conversations from getting stuck when the agent is blocked on AskUserQuestion and the user replies via the composer. It introduces a consistent “Something else” free-form escape hatch for question batches and ensures typed replies can interrupt a blocked run so the message is delivered as a new turn.
Changes:
- Add shared helpers for the “Something else” free-form option and detection of model-supplied equivalents.
- Update both UIs to append and render the free-form option for pending questions, including composer placeholder/focus behavior.
- Interrupt a run blocked on
ask_userwhen the user sends a reply, so queued messages are not stranded behind a non-idling run.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/common/ai/tools.ts | Adds shared “Something else” label/description helpers and detection for model-provided free-form options. |
| apps/ui/src/ui-classic/components/session-view/index.tsx | Tracks an armed free-form question and wires it into Conversation + Composer behavior. |
| apps/ui/src/ui-classic/components/session-view/conversation/style.module.css | Styles the appended free-form option as secondary until armed. |
| apps/ui/src/ui-classic/components/session-view/conversation/selection.test.tsx | Updates test harness to pass new Conversation props. |
| apps/ui/src/ui-classic/components/session-view/conversation/index.tsx | Renders the appended free-form option and forwards arming callbacks/state. |
| apps/ui/src/ui-classic/components/session-view/conversation/index.test.ts | Adds coverage for free-form option rendering/arming and de-duplication. |
| apps/ui/src/ui-classic/components/session-view/composer/index.tsx | Adds focus handle + placeholder/label logic for awaiting-answer and free-form mode. |
| apps/ui/src/data/queries/use-agent-run.tsx | Interrupts blocked ask_user runs when sending a reply so the queued message can dispatch. |
| apps/ui/src/data/queries/use-agent-run.test.tsx | Adds test coverage for interrupting blocked question runs before dispatching queued replies. |
| apps/studio/src/components/studio-code-session/use-agent-run.tsx | Mirrors the “interrupt blocked question runs on reply” behavior in the desktop UI hook. |
| apps/studio/src/components/studio-code-session/tests/use-agent-run.test.tsx | Adds desktop UI test coverage for interrupting blocked question runs before continuing. |
| apps/studio/src/components/studio-code-session/index.tsx | Tracks armed free-form question and wires it into Conversation + Composer focus/placeholder behavior. |
| apps/studio/src/components/studio-code-session/conversation/style.module.css | Visually distinguishes the appended free-form option (dashed border + secondary color). |
| apps/studio/src/components/studio-code-session/conversation/index.tsx | Renders the appended free-form option and forwards arming callbacks/state. |
| apps/studio/src/components/studio-code-session/conversation/index.test.tsx | Adds coverage for free-form option rendering/arming and de-duplication. |
| apps/studio/src/components/studio-code-session/composer/index.tsx | Adds placeholder logic for awaiting-answer/free-form and supports focus requests. |
| apps/cli/ai/tools/generate-images.ts | Switches progress reporting to tool context onProgress instead of CLI logger progress emission. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
📊 Performance Test ResultsComparing 19ee359 vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
…uestion-prompts-in-classic-studio-code-ui-v1 # Conflicts: # apps/cli/ai/tools/generate-images.ts
gavande1
left a comment
There was a problem hiding this comment.
@gcsecsey Thanks for working on this. I tested it and it works as expected. I saw a message that said following, is that expected? Also, in my ongoing session, it never prompted me to answer questions, it just kept going in chat format.
Thanks for testing @gavande1! 🙌 I think it must be an issue with these changes, earlier the prompts were always presented via the question prompt UI. I'll try to reproduce and check what's going wrong here. |

Related issues
How AI was used in this PR
It was used to identify and solve the issue.
Proposed Changes
AskUserQuestionblocks the agent until every question in the batch is answered. Until now, a message typed while those questions were on screen went into the follow-up queue, and that queue only drains when the run goes idle. A run waiting for answers never does, so the message sat there and nothing happened. Neither GUI offered a way out except picking one of the agent's options or pressing Stop.Open question for UX, @shaunandrews: should a typed reply answer the pending question instead of cancelling it? I'm not sure if the current changes are the right solution for this or not. We should come up with an elegant way of handling the "something else" options, ideally:
The CLI persists answers in a form the transcript hides from the message flow, so the typed text would vanish from the chat unless free-form answers are also rendered in both apps. The marker question resolves along with this one, since cancelling honestly earns the marker and answering never shows one.
Testing Instructions
Help me build a small WordPress plugin from scratch. Ask me what problem it should solve and how it should be structured.it should be a mu-pluginand send it.Pre-merge Checklist