Skip to content

feat: optional preview on question tool options - #41538

Open
adityasasidhar wants to merge 2 commits into
anomalyco:devfrom
adityasasidhar:question-option-preview
Open

feat: optional preview on question tool options#41538
adityasasidhar wants to merge 2 commits into
anomalyco:devfrom
adityasasidhar:question-option-preview

Conversation

@adityasasidhar

Copy link
Copy Markdown

Issue for this PR

Closes #40846

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Adds an optional preview to a question tool Option: a block of plain monospace text shown beside the option list, tracking whichever option is focused. An option without one behaves exactly as today.

The problem it solves: when a choice is between things that are inherently visual — two layouts, two implementations of the same function, two config shapes — a one-line description can't carry the difference. So the model dumps every variant into its message text before asking, and the prompt then appears below with bare labels like 1. Split 2. Stacked. The content and the choice get separated at the moment you need them together. This puts the comparison inside the prompt.

Where the pieces are:

  • Schemapackages/schema/src/question.ts (and the v1 QuestionOption) carries the field, plus normalizePreview and previewLayout.
  • Normalization at the tool boundarysanitize() in packages/core/src/tool/question.ts runs once on the way in: strips markdown fence markers, ANSI escapes and control characters, tabs to spaces, trims blank edges, and truncates past 2000 chars with a visible marker. Previews are dropped outright when multiple: true, since there's no single focused option for a pane to track. Doing this once at the boundary means no renderer has to defend itself against model output, and a preview can't fail the tool call — worst case it normalizes to undefined and the option renders as it does today.
  • LayoutpreviewLayout() derives every bound from the viewport, never from the content: rows are height/3 clamped to 4–12, the list column is 42% of content width clamped to 24–48, and the two-pane layout only engages when an option actually carries a preview and both columns clear 24 columns. Below 80 columns it falls back to single column. Long lines clip instead of wrapping so ASCII alignment survives. This part is deliberate — Long question tool makes opencode unusable #11367, [FEATURE]: Add a max % height and ability to scroll to the question pane (TUI) #18673 and [FEATURE]: The question tool takes too much screen real estate #11014 are all "the question UI outgrew my screen", and adding content to that prompt without bounding it would have made them worse.
  • Surfaces — the TUI prompt (packages/tui/src/routes/session/question.tsx), the run footer, and the web/desktop question dock.
  • Tool descriptionquestion.txt tells the model when not to reach for it; an unnecessary preview pane is noise.

The field is additive and optional, so there's no migration and no event version bump — clients that ignore it render exactly as before.

One open question, carried over from the issue and still unanswered: this targets Question.Option on dev. On the v2 line the question tool lowers into a Form and toField() maps options through { value, label, description }, so a preview would be silently dropped there. Form.Option may be the better home — it would give every form previews rather than just questions. Happy to retarget if that's preferred.

How did you verify your code works?

New tests, all passing:

  • packages/schema/test/question.test.ts (19) — normalization (fences, ANSI, control chars, blank-edge trimming, truncation) and the layout bounds across terminal sizes, including the narrow single-column fallback.
  • packages/core/test/tool-question.test.ts (7) — sanitize(), including previews being dropped for multi-select.
  • packages/opencode/test/tool/question.test.ts (3).

Also: full TUI suite passes (193 pass, 0 fail), bun turbo typecheck is clean across tui/core/opencode, and oxlint reports 0 errors on the changed files. Rebased onto current dev before opening.

Screenshots / recordings

Preview pane, first option focused Preview pane, second option focused

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

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.

[FEATURE]: Optional preview on question tool options for visual choices

1 participant