Skip to content

feat(desktop): skipped clarify keeps its choices visible and answerable - #69720

Closed
SHL0MS wants to merge 1 commit into
NousResearch:mainfrom
SHL0MS:feat/desktop-clarify-late-answer
Closed

feat(desktop): skipped clarify keeps its choices visible and answerable#69720
SHL0MS wants to merge 1 commit into
NousResearch:mainfrom
SHL0MS:feat/desktop-clarify-late-answer

Conversation

@SHL0MS

@SHL0MS SHL0MS commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

What does this PR do?

When a clarify prompt (multiple-choice question) times out, the settled card collapses to just the question and an italic "Skipped". The choices vanish — even though they're sitting right in the tool-call args — and there is no way to answer after the fact. If you stepped away and missed the window, you can't even see what the agent asked you to pick between.

This keeps the choices on the skipped card and makes them actionable:

  • The original options render on the settled card, letter-badged like the live prompt.
  • Clicking one drafts a quoted follow-up into the composer — Re: "<question>" — my answer: <choice> — and focuses it. Enter sends it as a normal user message; if the agent is mid-turn, it queues like any other prompt.
  • A hint line under the options explains the question timed out and what picking does.

Deliberately NOT retroactive resolution of the expired request: by the time the card shows "Skipped", the tool has already returned empty and the turn has moved on. Injecting a late answer into past context would break the prompt-cache and role-alternation invariants, and clarify.respond against an expired request id hard-errors today (#56558). The follow-up-message path needs zero backend changes and behaves identically against older backends.

Answered clarifies and free-text (no-choice) skips render exactly as before.

Related: #44845 tracks the real long-term design (durable, ID-addressable clarify decisions instead of short blocking timers) — this is the interim UX until that lands. #12625 / #33567 (timeout controls) are adjacent but untouched.

Related Issue

Interim UX for #44845.

Type of Change

  • ✨ New feature (non-breaking change that adds functionality)

Changes Made

  • apps/desktop/src/components/assistant-ui/clarify-tool.tsx: ClarifyToolSettled reads choices from the tool args; when the result is a skip and choices exist, renders them as buttons that draft the follow-up via the composer insert bus (requestComposerInsert + requestComposerFocus).
  • i18n: lateAnswer (template), lateAnswerTip, lateAnswerHint added to types.ts and all four locales (en, ja, zh, zh-hant).
  • Tests (clarify-tool.test.tsx): skipped-with-choices renders the options and a click emits the drafted follow-up on the insert bus; answered clarifies and choice-less skips render no late-choice group.

How to Test

  1. Ask the agent something that triggers a multiple-choice clarify, then don't answer until it times out (default 5 min, or lower approvals/clarify timeout for a faster repro).
  2. Before: the card shows the question + "Skipped" and nothing else. After: the original options are listed under the skip label.
  3. Click an option: the composer fills with Re: "<question>" — my answer: <choice> and focuses. Enter sends; if the agent is busy the message queues and the queue panel shows it.
  4. Answer a clarify normally: the settled card is unchanged (no options group).
  5. Renderer checks: cd apps/desktop && npx tsc -p . --noEmit && npx vitest run --project ui (1930 passed, 210 files); eslint clean on touched files (5 pre-existing-style document warnings in the test file match the repo's existing test patterns).

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run the desktop renderer suite (npx vitest run --project ui) and all tests pass; pytest N/A, no Python changes
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)
  • I've tested on my platform: macOS 26.5

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — or N/A (no docs describe the skipped-clarify rendering)
  • I've updated cli-config.yaml.example if I added/changed config keys — or N/A
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — or N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — or N/A (renderer-only)
  • I've updated tool descriptions/schemas if I changed tool behavior — or N/A

When a clarify prompt times out, the settled card collapsed to just
'Skipped' — the options were unrecoverable (the args carry them, the
renderer dropped them) and there was no way to answer late.

The skipped card now:
- renders the original choices, letter-badged like the live card
- clicking one drafts a quoted follow-up ('Re: "<question>" — my
  answer: <choice>') into the composer via the insert bus. Enter sends
  it; if the agent is mid-turn it queues like any other prompt.
- a hint line explains the question timed out and what picking does

No retroactive resolution of the expired request: the tool already
returned empty and the turn moved on — injecting into past context
would break prompt-cache and role-alternation invariants, and
clarify.respond on an expired id hard-errors (NousResearch#56558). The follow-up
message path needs no backend change and works against old backends.

Answered clarifies and free-text (no-choice) skips are unchanged.

Interim UX for NousResearch#44845 (durable ID-addressable clarify decisions).
@OutThisLife

Copy link
Copy Markdown
Collaborator

Superseded by #69769, which cherry-picks your commit (authorship preserved) and adds two refinements on top: a shared ChoiceButton so the live and settled cards stop duplicating markup, and neutral hint copy — an empty user_response is emitted for both a timeout and a manual Skip with no field to tell them apart, so "This question timed out" was wrong for the skip case. Same follow-up-message approach, same invariants. Thanks @SHL0MS — clean idea, nicely scoped.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have type/feature New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants