Skip to content

Picking the right Opus 4.7 variant takes hours and requires reverse-engineering the CLI source — every layer is hostile to discovery #3466

@JohnMavic

Description

@JohnMavic

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. Grep through the bundled minified app.js to find the cF model array and the Pqo/Rqo rename functions, just to map Hidden Model 3claude-opus-4.7-xhigh. This is the only place that information exists on my machine.
  6. 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.
  7. 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.
  8. 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:

  1. 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.
  2. 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.
  3. Add a /model --describe or hover description in the picker. Even one sentence per entry. Hidden Model 3 with no description is unusable.
  4. 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.
  5. 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

  1. Windows 11, fresh Copilot CLI 1.0.52-1 install
  2. Log in with an account entitled to internal Opus variants
  3. Edit settings.json to set "model": "claude-opus-4.7-xhigh"
  4. Run copilot, wait for session start
  5. Reopen settings.json → field has been changed back to "claude-opus-4.7"
  6. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:configurationConfig files, instruction files, settings, and environment variablesarea:modelsModel selection, availability, switching, rate limits, and model-specific behavior

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions