[Bug]: chatgpt model cannot switch tiers — the picker is now a Radix popover that ignores synthetic events
- Dominant language
- JavaScript
- Stars
- 29.5k
- Forks
- 2.9k
- Avg merge
- 15h 36m
- Merged PRs (30d)
- 70
Description
### Description
`opencli chatgpt model ` can no longer switch tiers on the current chatgpt.com frontend (observed 2026-09-05, opencli 1.8.7, extension v1.0.24, zh-TW Pro account).
This is a root-cause report, not a fix. I could not repair it at the adapter layer; the evidence points at the page abstraction.
The error message changes with how far the adapter gets, so there are three stacked breakages:
| State | Error |
|---|---|
| Stock 1.8.7 | `Could not find the ChatGPT model selector in the composer.` |
| After teaching it the new button selector | `ChatGPT model did not switch to .` |
| After also fixing tier readback | `Could not click the ChatGPT model option.` |
### Steps to Reproduce
1. `opencli chatgpt model pro --window background --trace retain-on-failure`
```
ok: false
error:
code: COMMAND_EXEC
message: Could not find the ChatGPT model selector in the composer.
```
2. Rule out auth: `opencli chatgpt status` reports `Connected`, `Login: 'Yes'`, and `opencli chatgpt whoami` resolves the account.
3. Inspect the picker button on the live bound tab:
```
opencli browser eval "(() => { const p = document.querySelector('button[class*=\"__composer-pill\"]'); return JSON.stringify({ testid: p.getAttribute('data-testid'), aria: p.getAttribute('aria-label'), haspopup: p.getAttribute('aria-haspopup') }); })()"
→ {"testid":null,"aria":null,"haspopup":"menu"}
```
4. Open it with a real CDP click, then read the menu:
```
opencli browser click "button[class*=__composer-pill]"
opencli browser eval "JSON.stringify(Array.from(document.querySelectorAll('[role=\"menuitemradio\"]')).map(r => r.textContent.trim()))"
→ ["最新的","GPT-5.6 Sol","GPT-5.5"]
```
### Expected Behavior
`opencli chatgpt model pro` selects the Pro tier and reports `Success` or `Already selected`.
### Root cause
**1. The picker button lost every selector the adapter looks for.**
`menuButtonSelectors` looks for `button[data-testid="model-switcher-dropdown-button"]` and `button[aria-label*=...]`. The current button has neither — no `data-testid`, `aria-label` is `null`. It is identifiable only by class and popup attributes:
```
class="__composer-pill __composer-pill--neutral ..."
aria-haspopup="menu" aria-expanded="false" data-state="closed"
id="radix-_r_4e_" interestfor="_r_4g_"
style="anchor-name: --anchor-_r_4g_;"
```
The `radix-*` id, `interestfor`, and `anchor-name` indicate Radix UI on top of the HTML Popover API, Interest Invokers, and CSS Anchor Positioning. (Those generated ids differ per render — they are shown as evidence of the stack, not as stable selectors.)
**2. The tier list is no longer a set of menu items — it is a slider.**
With the popover open, `[role="menuitemradio"]` yields three entries, and they are *model families*, not tiers: `["最新的", "GPT-5.6 Sol", "GPT-5.5"]`.
The tier itself is a slider. The menu's accessible text reads (zh-TW): 「第 5 項,共 5 項。使用向左鍵與向右鍵調整效能。」 — item 5 of 5, adjust with left/right arrow keys.
This breaks the `intelligenceOptions.length === 5` branch in `selectChatGPTModel`, which assumes five clickable tier options.
**3. Tier readback parses the button text, which no longer word-breaks.**
`getCurrentChatGPTModel` falls back to matching the composer button's `textContent` against known labels using:
```js
new RegExp('(^|\\b)' + label + '(\\b|$)', 'i')
```
The button's `textContent` is now `"6Pro"` with no separator. `6` and `P` are both word characters, so there is no `\b` between them and `\bPro\b` cannot match; the current tier reads as `null`. Locally, `(?
Contributor guide
Research direction
Start with selectChatGPTModel, getCurrentChatGPTModel, setChatGPTModelConfig, and the page.nativeClick path, then reproduce with `opencli chatgpt model pro --window background --trace retain-on-failure`. Done means the live ChatGPT picker reliably selects the requested tier and reports Success or Already selected; the issue notes that keyboard navigation or a single-context locate-and-click flow still needs verification.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript
- Domain
- cli, devtools
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100