Skip to content

fix(tui): color Fable models in the Anthropic palette like Opus - #762

Merged
junhoyeo merged 3 commits into
mainfrom
fix/tui-fable-anthropic-color
Jun 22, 2026
Merged

fix(tui): color Fable models in the Anthropic palette like Opus#762
junhoyeo merged 3 commits into
mainfrom
fix/tui-fable-anthropic-color

Conversation

@junhoyeo

@junhoyeo junhoyeo commented Jun 22, 2026

Copy link
Copy Markdown
Owner

Color Fable models the same as Opus in the Overview tab

Problem

In the TUI Overview tab, Anthropic models are colored from ANTHROPIC_SHADES (the orange palette). But Fable models rendered gray (the UNKNOWN_SHADES fallback) instead of the Anthropic color Opus gets.

Root cause

Two functions classify a model's provider, and neither recognized the fable token — only claude/opus/sonnet/haiku:

  • crates/tokscale-core/src/provider_identity.rsinferred_provider_from_model (drives attribution/grouping app-wide)
  • crates/tokscale-cli/src/tui/ui/widgets.rsget_provider_from_model (TUI color fallback)

The claude-fable-5 form slipped through via the "claude" substring, but the bare/normalized fable-5 form (which the pricing layer already produces) fell through to "unknown" → gray.

Fix

Add fable to the Anthropic branch in both functions. Now every Fable form (fable-5, claude-fable-5, claude-fable-5[1m]) maps to anthropic and shares the same base color/level as Opus.

Tests

  • provider_identity: all three Fable forms → Some("anthropic").
  • get_provider_from_model("fable-5") == "anthropic".
  • get_model_color("fable-5") == get_model_color("claude-opus-4-1") and != the unknown shade.

Note

Within the Anthropic palette the exact shade is cost-ranked by design (rank 0 = highest-cost = base orange), so a Fable and an Opus model still differentiate by cost when both are present — this PR fixes the family/base-level (no longer gray). If you'd prefer Fable pinned to Opus's exact shade regardless of cost, that's a separate design change — happy to follow up.

🤖 Generated with Claude Code


Summary by cubic

Fable models now render in the Anthropic palette (like Opus) in the TUI Overview. We recognize fable as a delimited token so bare fable-5 is orange and unrelated names aren’t misclassified.

  • Bug Fixes
    • Added fable to the Anthropic branch in inferred_provider_from_model (@tokscale-core) and get_provider_from_model (@tokscale-cli).
    • All Fable IDs (fable-5, claude-fable-5, claude-fable-5[1m]) map to anthropic and share Opus’s base color; within-provider shade stays cost-ranked.
    • Match fable only as a delimited token in the TUI and add tests for inference, color mapping, and substring regressions; make the color test config-independent.

Written for commit ff3b907. Summary will update on new commits.

Review in cubic

Fable is a Claude model family, but neither `inferred_provider_from_model`
(core) nor `get_provider_from_model` (TUI) recognized the `fable` token —
only `claude`/`opus`/`sonnet`/`haiku`. As a result a bare `fable-5` id was
attributed to the "unknown" provider and rendered with the gray
UNKNOWN_SHADES in the Overview tab instead of the Anthropic orange that
Opus gets. (The `claude-fable-5` form happened to match via "claude", so
the bug only bit the bare/normalized forms.)

Add `fable` to the Anthropic branch in both functions so every Fable form
maps to Anthropic and shares the same base color/level as Opus.

Tests: provider_identity maps fable-5 / claude-fable-5 / claude-fable-5[1m]
to "anthropic"; get_provider_from_model recognizes fable; and
get_model_color("fable-5") == get_model_color("claude-opus-4-1") (and != the
unknown shade).

Confidence: high
Scope-risk: narrow
Not-tested: exact cost-ranked shade in build_model_shade_map (the base-color level is asserted; within-provider shade remains cost-ranked by design)
@vercel

vercel Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
tokscale Ignored Ignored Preview Jun 22, 2026 10:35am

Request Review

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 2 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread crates/tokscale-cli/src/tui/ui/widgets.rs Outdated
Comment thread crates/tokscale-cli/src/tui/ui/widgets.rs Outdated
junhoyeo added 2 commits June 22, 2026 19:26
Address automated review feedback on PR #762.

P2: get_provider_from_model used a raw substring match for "fable", which
could misclassify unrelated names (e.g. "unfabled-x") as Anthropic and
drift from core inference. Match "fable" only as a delimited token,
mirroring core provider_identity::contains_delimited.

P3: fable_gets_same_base_color_as_opus asserted default-palette color
inequality against an unknown model, which a user's ~/.tokscale color
override could break. Assert provider classification instead, which is
config-independent.

Constraint: get_provider_from_model is a TUI-local mapping with a wider
provider set than core, so fix is applied locally rather than reusing
core's private contains_delimited.
Rejected: Re-export core contains_delimited | larger surface than needed
Confidence: high
Scope-risk: narrow
…ic-color

# Conflicts:
#	crates/tokscale-cli/src/tui/ui/widgets.rs
@junhoyeo
junhoyeo merged commit afa65ed into main Jun 22, 2026
3 of 4 checks passed
makoMakoGo added a commit to makoMakoGo/tokscale that referenced this pull request Jun 23, 2026
ported from upstream junhoyeo#760
ported from upstream junhoyeo#762
ported from upstream junhoyeo#763
ported from upstream junhoyeo#764
t1000040 pushed a commit to tmobi-internal/tokscale that referenced this pull request Jun 30, 2026
…oyeo#762)

* fix(tui): color Fable models in the Anthropic palette like Opus

Fable is a Claude model family, but neither `inferred_provider_from_model`
(core) nor `get_provider_from_model` (TUI) recognized the `fable` token —
only `claude`/`opus`/`sonnet`/`haiku`. As a result a bare `fable-5` id was
attributed to the "unknown" provider and rendered with the gray
UNKNOWN_SHADES in the Overview tab instead of the Anthropic orange that
Opus gets. (The `claude-fable-5` form happened to match via "claude", so
the bug only bit the bare/normalized forms.)

Add `fable` to the Anthropic branch in both functions so every Fable form
maps to Anthropic and shares the same base color/level as Opus.

Tests: provider_identity maps fable-5 / claude-fable-5 / claude-fable-5[1m]
to "anthropic"; get_provider_from_model recognizes fable; and
get_model_color("fable-5") == get_model_color("claude-opus-4-1") (and != the
unknown shade).

Confidence: high
Scope-risk: narrow
Not-tested: exact cost-ranked shade in build_model_shade_map (the base-color level is asserted; within-provider shade remains cost-ranked by design)

* fix(tui): match fable as delimited token + make color test hermetic

Address automated review feedback on PR junhoyeo#762.

P2: get_provider_from_model used a raw substring match for "fable", which
could misclassify unrelated names (e.g. "unfabled-x") as Anthropic and
drift from core inference. Match "fable" only as a delimited token,
mirroring core provider_identity::contains_delimited.

P3: fable_gets_same_base_color_as_opus asserted default-palette color
inequality against an unknown model, which a user's ~/.tokscale color
override could break. Assert provider classification instead, which is
config-independent.

Constraint: get_provider_from_model is a TUI-local mapping with a wider
provider set than core, so fix is applied locally rather than reusing
core's private contains_delimited.
Rejected: Re-export core contains_delimited | larger surface than needed
Confidence: high
Scope-risk: narrow
@junhoyeo
junhoyeo deleted the fix/tui-fable-anthropic-color branch July 13, 2026 02:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant