TL;DR
I spent over an hour just trying to make Copilot CLI consistently use the Opus 4.7 reasoning variant my account is entitled to. Every part of the system that should help — settings, picker, status line, docs — actively works against discovery. The end result is a hand-written PowerShell wrapper that overwrites settings.json before every launch, because the CLI silently overwrites it back on each start. This is not a workflow. This is symptomatic of a UX nobody walked through end-to-end.
What it took
In order to actually run on claude-opus-4.7-xhigh reliably, I had to:
- Try setting
model: "claude-opus-4.7-xhigh" in settings.json → CLI silently rewrote it to claude-opus-4.7 on next start. No warning, no notification, no log entry surfaced to me. The file just changed.
- Try the
/model picker → It lists my entitled internal variants only as Hidden Model 1, Hidden Model 2, Hidden Model 3. There is no tooltip, no description, no ? action. I have no way to know which one is xhigh without external help.
- Try
copilot --model claude-opus-4.7-xhigh -p "OK" → works fine, returns OK. So the backend entitlement is clearly there. But the interactive CLI gives me no path to that.
- Compare to a second machine on the same GitHub account → that one shows all four variants by their real names (
Claude Opus 4.7 (Extra high reasoning) (Internal only) etc.). Same account, same CLI version, completely different picker contents. No setting, no flag, no env var I can find explains the divergence.
- Grep through the bundled minified
app.js to find the cF model array and the Pqo/Rqo rename functions, just to map Hidden Model 3 → claude-opus-4.7-xhigh. This is the only place that information exists on my machine.
- Inspect
events.jsonl across multiple sessions to confirm that the effective model at runtime actually matches what I set — because the UI gives me no honest indication.
- Inspect
config.json to find an ExP flag (copilot_cli_opus_medium_effort_default: true) that appears to be steering this behavior server-side, with zero documentation anywhere.
- Write a PowerShell wrapper function that rewrites
settings.json before every launch. This is now the only reliable way to stay on the model I'm entitled to.
That is, conservatively, an hour of investigation. None of it should have been necessary.
Where the system actively fails the user
- Silent overwrites of user config. If the CLI is going to refuse my chosen model, it must at minimum tell me why. Right now
settings.json mutates between sessions with no audit trail visible to the user.
- No discoverability in the picker.
Hidden Model 3 ✓ next to my selected entry tells me literally nothing. I cannot make a meaningful choice from this UI.
- No status visibility of the effective model. The footer shows generic marketing names ("Claude Opus 4.7") and gives me no way to know whether xhigh, high, or base is actually loaded. The same label covers four different runtime configurations.
- No documentation. Searching the public repo, docs, and GitHub for "Hidden Model" /
claude-opus-4.7-xhigh / copilot_cli_opus_medium_effort_default returns nothing useful. Every piece of state that affects the model is undocumented.
- Same-account inconsistency. Two machines, one account, identical CLI version, totally different model lists. If this is intentional (ExP / streamerMode / device classification), it needs to be surfaced. Right now it just looks broken.
What I want
I'm not asking for the Internal-only models to be exposed publicly. I'm asking that, given I am entitled to them, the CLI stops actively obstructing me from using them:
- Stop overwriting
settings.json.model silently. If the chosen model isn't permitted in the current ExP bucket or session context, show me one line in the UI: "Model claude-opus-4.7-xhigh reverted to default because: ". Anything but the current zero-feedback rewrite.
- Show the effective model + effort in the status line. Not just "Claude Opus 4.7" — show "Claude Opus 4.7 · xhigh" or equivalent. The user must be able to verify at a glance.
- Add a
/model --describe or hover description in the picker. Even one sentence per entry. Hidden Model 3 with no description is unusable.
- Document the ExP-driven divergence. Why do two machines under the same account see different picker contents? If
streamerMode / device classification / region is the reason, write it down so I don't waste another hour next time.
- A first-party way to lock a model. A PowerShell wrapper that mutates the config file before every launch is an embarrassing workaround. There should be a CLI flag or an env var (
COPILOT_MODEL=claude-opus-4.7-xhigh) that the CLI respects and does not silently override.
Repro
- Windows 11, fresh Copilot CLI 1.0.52-1 install
- Log in with an account entitled to internal Opus variants
- Edit
settings.json to set "model": "claude-opus-4.7-xhigh"
- Run
copilot, wait for session start
- Reopen
settings.json → field has been changed back to "claude-opus-4.7"
- Verify in
events.jsonl that session.model_change fired with the original value, then reverted — no user-visible log of why
Environment
- OS: Windows 11 Enterprise 10.0.26200
- Shell: PowerShell 7.6.2 Core, ConsoleHost
- CLI: 1.0.52-1
- Account: Microsoft FTE, entitled to all
claude-opus-4.7-* variants (backend-confirmed via direct -p invocation)
- Reproduces across multiple fresh sessions, persists after settings reset, persists after reinstall consideration
Why I'm filing this sharply
I'm a Microsoft employee. I write software for a living. If I spent an hour reverse-engineering a minified bundle to find out which Hidden Model is which, what does this look like to a non-engineer trying the CLI for the first time? Every layer of this UX is consistent in one thing: it does not respect the user's time. That has to change.
TL;DR
I spent over an hour just trying to make Copilot CLI consistently use the Opus 4.7 reasoning variant my account is entitled to. Every part of the system that should help — settings, picker, status line, docs — actively works against discovery. The end result is a hand-written PowerShell wrapper that overwrites
settings.jsonbefore every launch, because the CLI silently overwrites it back on each start. This is not a workflow. This is symptomatic of a UX nobody walked through end-to-end.What it took
In order to actually run on
claude-opus-4.7-xhighreliably, I had to:model: "claude-opus-4.7-xhigh"insettings.json→ CLI silently rewrote it toclaude-opus-4.7on next start. No warning, no notification, no log entry surfaced to me. The file just changed./modelpicker → It lists my entitled internal variants only asHidden Model 1,Hidden Model 2,Hidden Model 3. There is no tooltip, no description, no?action. I have no way to know which one is xhigh without external help.copilot --model claude-opus-4.7-xhigh -p "OK"→ works fine, returns OK. So the backend entitlement is clearly there. But the interactive CLI gives me no path to that.Claude Opus 4.7 (Extra high reasoning) (Internal only)etc.). Same account, same CLI version, completely different picker contents. No setting, no flag, no env var I can find explains the divergence.app.jsto find thecFmodel array and thePqo/Rqorename functions, just to mapHidden Model 3→claude-opus-4.7-xhigh. This is the only place that information exists on my machine.events.jsonlacross multiple sessions to confirm that the effective model at runtime actually matches what I set — because the UI gives me no honest indication.config.jsonto find an ExP flag (copilot_cli_opus_medium_effort_default: true) that appears to be steering this behavior server-side, with zero documentation anywhere.settings.jsonbefore every launch. This is now the only reliable way to stay on the model I'm entitled to.That is, conservatively, an hour of investigation. None of it should have been necessary.
Where the system actively fails the user
settings.jsonmutates between sessions with no audit trail visible to the user.Hidden Model 3 ✓next to my selected entry tells me literally nothing. I cannot make a meaningful choice from this UI.claude-opus-4.7-xhigh/copilot_cli_opus_medium_effort_defaultreturns nothing useful. Every piece of state that affects the model is undocumented.What I want
I'm not asking for the Internal-only models to be exposed publicly. I'm asking that, given I am entitled to them, the CLI stops actively obstructing me from using them:
settings.json.modelsilently. If the chosen model isn't permitted in the current ExP bucket or session context, show me one line in the UI: "Modelclaude-opus-4.7-xhighreverted to default because: ". Anything but the current zero-feedback rewrite./model --describeor hover description in the picker. Even one sentence per entry.Hidden Model 3with no description is unusable.streamerMode/ device classification / region is the reason, write it down so I don't waste another hour next time.COPILOT_MODEL=claude-opus-4.7-xhigh) that the CLI respects and does not silently override.Repro
settings.jsonto set"model": "claude-opus-4.7-xhigh"copilot, wait for session startsettings.json→ field has been changed back to"claude-opus-4.7"events.jsonlthatsession.model_changefired with the original value, then reverted — no user-visible log of whyEnvironment
claude-opus-4.7-*variants (backend-confirmed via direct-pinvocation)Why I'm filing this sharply
I'm a Microsoft employee. I write software for a living. If I spent an hour reverse-engineering a minified bundle to find out which Hidden Model is which, what does this look like to a non-engineer trying the CLI for the first time? Every layer of this UX is consistent in one thing: it does not respect the user's time. That has to change.