Skip to content

[Bug]: Claude Code model picker is stale and connection test hides the resolved model #6180

Description

@MumuTW

What happened?

The Claude Code model picker uses a hard-coded fallback catalog that still recommends:

  • claude-opus-4-5
  • claude-sonnet-4-5
  • claude-haiku-4-5

This catalog is stale. Anthropic's current primary model lineup includes:

  • claude-fable-5
  • claude-opus-5
  • claude-sonnet-5
  • claude-haiku-4-5

The same stale list is present on the current main branch as of 2026-07-28:
https://github.com/nexu-io/open-design/blob/main/apps/daemon/src/runtimes/defs/claude.ts#L6-L14

Because Claude Code does not expose a machine-readable list-models subcommand, this fallback list becomes the primary set of explicit suggestions shown to users. Rolling aliases partially mitigate the problem, but the UI still prominently recommends obsolete pinned model IDs.

Open Design Cloud already recognizes claude-fable-5, making the two model catalogs inconsistent. Fable 5 should be an explicit first-class choice in the Claude Code picker, not only something advanced users can discover and type into the Custom field. It is a particularly important option for frontend/UI work and is likely to be a common user selection.

There is also a related transparency problem in the connection test. If a user selects opus (alias) and clicks Test, the success message only says that Claude Code replied in N milliseconds. It does not reveal which concrete model the alias resolved to, so the test cannot actually confirm the model selection.

This is not an upstream limitation: Open Design already parses the concrete model from Claude's system/init stream event in apps/daemon/src/runtimes/claude-stream.ts (obj.model). However, the connection-test sink ignores that status event, ConnectionTestResponse.model continues to contain the requested slot (opus), and the frontend success copy does not display any model.

Steps to reproduce

  1. Install and open Open Design 0.16.1 on macOS.
  2. Open Settings.
  3. Find the Claude Code agent card.
  4. Open the model picker.
  5. Observe that the explicit model list only contains Claude 4.5 models.
  6. Observe that Claude Fable 5, Opus 5, and Sonnet 5 are absent.
  7. Select Opus (alias) and click Test.
  8. Observe that the success result reports only the agent name, latency, and sample (OK), without the concrete model that answered.

Expected behavior

The built-in fallback list should reflect Anthropic's current model lineup, for example:

  • Best available (alias)
  • Sonnet (alias)
  • Opus (alias)
  • Haiku (alias)
  • claude-fable-5
  • claude-opus-5
  • claude-sonnet-5
  • claude-haiku-4-5

Fable 5 should be present as an explicit option because it is a major current model and a common choice for frontend/UI work.

When testing an alias or the CLI default, the result should display the concrete model reported by Claude Code, for example:

Claude Code replied in 812 ms — Model: claude-opus-5OK

The response contract should preserve both values rather than overloading one field:

  • model: requested selection, such as opus or default
  • resolvedModel (or reportedModel): concrete model reported by the CLI, such as claude-opus-5

Relevant Anthropic documentation:
https://platform.claude.com/docs/en/about-claude/models/choosing-a-model

Open Design version

0.16.1

Platform

macOS (Apple Silicon)

Additional context

Anthropic provides an authenticated Models API at GET /v1/models, even though Claude Code itself does not expose a machine-readable list-models subcommand:

https://platform.claude.com/docs/en/api/models/list

A more robust discovery and fallback strategy would be:

  1. Query /v1/models when an Anthropic API key is available.
  2. Prefer rolling Claude Code aliases (best, sonnet, opus, haiku) for subscription and CLI-only users.
  3. Maintain a small, current fallback catalog for explicit model IDs, including Fable 5.
  4. Keep Custom model ID support for gateways and third-party providers.
  5. Add a test or release checklist that prevents retired model generations from remaining the primary built-in suggestions.

Claude Code supports --model <alias|name>, and rolling aliases are safer fallback choices because they can resolve to provider-appropriate recommended versions:

https://code.claude.com/docs/en/model-config

A minimal implementation for resolved-model reporting appears to be:

  1. Capture model from the existing Claude status/initializing event in createAgentSink() instead of discarding it.
  2. Add an optional resolvedModel/reportedModel field to ConnectionTestResponse.
  3. Return it from successful local-agent tests.
  4. Append it to the existing localized success message, avoiding duplicate display when it equals the requested exact ID.
  5. Add a regression test covering opus as the requested alias and claude-opus-5 as the reported concrete model.

Major Claude model releases are infrequent enough that retaining outdated Claude 4.5 entries across multiple generations appears to be a fallback-catalog maintenance failure rather than an unavoidable technical limitation.

Preflight

  • I searched existing open issues and confirmed this is not a duplicate.
  • This report includes the real behavior, reproduction steps, expected result, app version, and platform.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions