fix(pi): show an extension dialog's title once#22463

merged3
main
GitHub fork: r10/h5-1
opened21d agobyOonly21mil
View on GitHubTwo-way sync enabledPR last imported 9d ago

Problem

A Pi extension that asks with ctx.ui.select(title, options) or ctx.ui.editor(title) shows the whole title twice in the pending question panel, once in the header row and again as the question. An input dialog without a placeholder does the same. A long or multi-line title, like the ones rpiv-ask-user-question sends, also fills the header row, runs past the card edge and leaves no room for the collapsed preview.

Pi's RPC select and editor requests carry only a title (plus options or prefill), with no message or placeholder. piQuestion set header: title and fell back to question = title, so both fields got the same text.

Change

When a Pi dialog has no message or placeholder, piQuestion now shows the title once, as the question, under the "Question" header that the Codex, Grok and Antigravity adapters already use when a question has no header of its own. An input dialog with a non-blank placeholder keeps its title as the header, as before. A blank placeholder counts as none, as main does since #23235, so that dialog also shows its title once under "Question". Answers are keyed by question id, so the responses sent to Pi do not change.

This covers the duplicated title in #17895. On current main the expanded question already keeps its line breaks (screenshots below), so this PR does not touch the renderers.

Scope and approval

Fixes the duplicated-title part of #17895, which has no maintainer triage yet. I'm submitting it as a very small, focused fix for an obvious bug. The panel showed the same text twice, and the issue's expected behavior is that the title appears once. The change touches only the line the issue's diagnosis names. It doesn't change any default, setting or answer sent to Pi. Prior PRs: none. No open or closed PR references #17895 or changes piQuestion.

Verification

  • Focused tests, from packages/provider-pi: vp test run src/server/adapter.test.ts -t "input dialog|empty select option|editor prefill". The existing select and editor tests now also assert the header and question, and a new test pins an input dialog with a placeholder. With main's adapter.ts, the two title-only cases fail because the header is the title, and the placeholder case passes. With this change all three pass.
  • Full packages/provider-pi suite: 128 of 128 pass. tsc-rs --noEmit exits 0. vp fmt --check passes on both files. vp lint exits 0 with main's existing unused layer warning.
  • Real Pi in the web app. I ran Pi 1.3.0 in RPC mode with one extension command, /merge-target, that calls ctx.ui.select with a five-line title and the options main and dev, plus a placeholder local model entry so T3 lists Pi as available. No model request is made. Pi sends {"method":"select","title":"Merge target\n\nWhich branch should this change merge into?\n\n...","options":["main","dev"]} with no message or placeholder. The T3 server and web dev server ran from source with a fresh state dir, once with main's adapter.ts and once with this branch, in Chrome 155 at 1920x1081. Each time I picked /merge-target from the composer menu, sent it and captured the panel as it opened, then clicked the header row to collapse it.

Main, panel open: the whole title is the header row, running past the card edge over the toggle icon, and it repeats as the question.

Main: the full title fills the header row and repeats as the question

This branch, panel open: the header reads "Question" and the title appears once, with its line breaks.

Branch: the header reads Question and the title appears once

Main, collapsed: the header row still holds the full title, so the preview has no room.

Main collapsed: the header row holds the full title

This branch, collapsed: "Question" followed by a truncated preview of the title.

Branch collapsed: Question followed by a truncated preview

This branch, after clicking main: the panel closes and the extension's own notice, "Merge target: main", shows that Pi received the answer.

Branch: after answering, the thread shows the extension's notice Merge target: main

Focused tests with main's adapter.ts, captured before #22557 deleted the bare input test: three failures, each with the title where "Question" was expected.

Focused tests on main: three header assertions fail

Focused tests on this branch, same earlier run: all four pass.

Focused tests on this branch: all four pass

Not checked:

  • Mobile. PendingUserInputCard renders the same header and question fields, so I expect the same result there, but I did not run a simulator or emulator.
  • Pi editor and bare input dialogs in the app. A unit test covers editor; bare input takes the same no-message, no-placeholder branch.
  • The rpiv-ask-user-question extension itself. The test extension sends the same request shape, a multi-line title with options.
  • The desktop app, Windows and macOS.

Generated with Claude Opus 5.5 in T3 Code Nightly

Checks

22 successful · 12 skipped
All checks passed
6d68bed

Added 1 commit

  • fix(pi): show an extension dialog's title onceeb2deca
Synced from GitHub

Approvability

Verdict: Approved at eb2deca

Macroscope's review found this PR approvable — This narrowly fixes duplicated extension-dialog titles in the Pi provider by separating titles from messages/placeholders while preserving request and response behavior. Focused tests cover title-only dialogs and placeholder-based inputs.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

ℹ️ Recent review info
⚙️ Run configuration
📥 Commits

Reviewing files that changed from the base of the PR and between f64f2b2525341a2dcdc07af8f820119d036444ce and 6d68bed0d3cd7598af52c15f17cb612ed2774a9c.

📒 Files selected for processing: 2
  • packages/provider-pi/src/server/adapter.test.ts
  • packages/provider-pi/src/server/adapter.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 5 remain after this review.

Walkthrough

The Pi adapter now maps dialog titles and nonblank detail text to question headers and question text. Tests cover input, select, and editor dialogs.

Changes: Pi dialog question labels

Layer / File(s)Summary
Dialog question mapping
packages/provider-pi/src/server/adapter.ts, packages/provider-pi/src/server/adapter.test.ts
piQuestion uses the title as the header and the first nonblank message or placeholder as the question when detail text exists. Otherwise, it uses "Question" as the header and the title as the question. Tests cover input, select, and editor dialogs.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: juliusmarminge

Merge Risk: External image Minimal · up to 6d68b

The dialog presentation change is ready to merge with no identified user-facing or operational risk.

Architecture risk: External image Low · up to f64f2

The change affects 1 system.

Changed systems: packages/provider-pi

Architecture concerns No architecture-level concerns identified.

Review details

Systems and components

  • observed — packages/provider-pi (library) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in packages/provider-pi/src/server/adapter.ts: piQuestion now avoids repeating the title: dialog message or placeholder text becomes the question, the header uses the title, and dialogs without detail use "Question" as the header while retaining the title as the question.
  • observed — Modified behavior in packages/provider-pi/src/server/adapter.test.ts: Added a test asserting that an input dialog maps title to the question header and placeholder to the question text.
  • observed — Modified behavior in packages/provider-pi/src/server/adapter.test.ts: Updated the select-dialog test to expect the default "Question" header while retaining "Pick a tag" as the question text.
  • observed — Modified behavior in packages/provider-pi/src/server/adapter.test.ts: Updated the editor-dialog test to expect the default "Question" header.
Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title is concise, specific, and accurately summarizes the primary change: preventing a Pi extension dialog title from appearing twice.
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Description checkPassedThe description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the bug, the implementation, the approval rationale for the focused fix, focused and …
Full details: Description check

Explanation

The description includes all required sections: Problem, Change, Scope and approval, and Verification. It explains the bug, the implementation, the approval rationale for the focused fix, focused and broader test results, manual web-app verification, screenshots, and unverified platforms or scenarios.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Added 2 commits

  • Merge main (05696c636e) into r10/h5-1f64f2b2
  • Merge main (24c063ae80) into r10/h5-16d68bed

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

Verified unchanged head 6d68bed0d3cd7598af52c15f17cb612ed2774a9c on this Linux Boat VM with repository Playwright and /usr/bin/google-chrome at 1440x1000. Projects and threads were created through the app against a real git repository. No mocks, injected protocol events, or demo fixtures.

I reproduced the duplicate on fetched github/main (15fe283272) in /home/user/main, stopped that server, then ran the exact PR head. Both used the same prompt, question, options, repository and viewport. The older PR head has unrelated UI differences from current main.

Real Pi 1.4.0 ran the published @juicesharp/rpiv-ask-user-question 2.15.0 extension with gpt-6.1-sol through the VM proxy. Main repeated [Merge target] Which branch should this change merge into? in the pending panel header and body. This head shows Question as the header and the title once as the question. Collapse and expand preserve the question and options. Selecting main reached the extension and the model replied main.

Neighboring behavior passed: a custom answer in the select panel returned release-candidate; choosing Type something. opened the real blank-placeholder input with its multiline title shown once, and submitting release-candidate-2 returned that exact answer. Separate Codex gpt-6.1-sol turns completed on both revisions with codex verification ready.

Runtime/check transcript:

text
1git worktree add ../main github/main
2(main) timeout 600 vp i
3(main) background vp run dev: server 16733, web 8693
4main: duplicate pending-panel title reproduced; answer main returned
5stop captured main process group before starting PR
6(PR) timeout 600 vp i
7(PR) background vp run dev: server 13773, web 5733
8PR: Question header; main, release-candidate, release-candidate-2 returned
9blacksmith-check run: vp i && cd packages/provider-pi &&
10 vp test run src/server/adapter.test.ts -t "input dialog|empty select option|editor prefill"
114 passed, 84 skipped by the name filter
12latest head CI: no failing or pending checks; some jobs skipped

Before, current main:

main duplicates the pending question title

After, exact PR head:

pr shows Question and the title once

Collapse, expand, answer selection and the returned answer:

real pi question interaction and returned main answer

Real extension input with a blank placeholder:

blank-placeholder input preserves the multiline question without duplicating its title

I inspected the captures and checked uploaded video playback through its end and seeking.

Not verified

Native iOS/Android, Electron, macOS/Windows, remote/relay/tunnel connections, other provider adapters, Pi editor dialogs and nonblank-placeholder inputs in the running app. Focused adapter checks cover editor prefill and placeholder input mapping, but do not replace runtime checks.

The initial Pi Responses API configuration failed before any dialog with an incomplete empty upstream response. Configuring the proxy with its working chat-completions API resolved it; successful Pi checks used that configuration. No application fix or push was needed.