Skip to content

Discover Claude models from SDK initialization#4477

Open
colonelpanic8 wants to merge 3 commits into
pingdotgg:mainfrom
colonelpanic8:fix/discover-claude-models
Open

Discover Claude models from SDK initialization#4477
colonelpanic8 wants to merge 3 commits into
pingdotgg:mainfrom
colonelpanic8:fix/discover-claude-models

Conversation

@colonelpanic8

@colonelpanic8 colonelpanic8 commented Jul 24, 2026

Copy link
Copy Markdown

What Changed

  • Read Claude model IDs, display names, and native capabilities from the SDK initialization response.
  • Use the existing version-gated catalog only when live discovery is unavailable, while preserving configured custom models.
  • Forward options selected for newly discovered model IDs through interactive sessions and text generation.
  • Add focused coverage for discovery, fallback behavior, capability mapping, and dynamic option forwarding.

Why

Claude Code already exposes its current, account-aware model inventory through initializationResult(). Maintaining a second primary catalog in T3 Code goes stale when Claude adds models or aliases, which is why current Opus 5-backed entries were missing from the picker.

UI Changes

No component or layout changes. The model picker now mirrors the live Claude CLI inventory; an isolated app verification showed Default (recommended), Opus (1M context), Fable, Sonnet, and Haiku, with the discovered Opus reasoning levels and Fast Mode available.

Checklist

  • vp check (0 errors; 11 unrelated existing warnings)
  • vp run typecheck
  • vp test run apps/server/src/provider/Layers/ClaudeCapabilitiesProbe.test.ts apps/server/src/provider/Layers/ProviderRegistry.test.ts apps/server/src/provider/Layers/ClaudeAdapter.test.ts apps/server/src/textGeneration/ClaudeTextGeneration.test.ts (114 tests)
  • Isolated test-t3-app model-picker verification

Note

Discover Claude models from SDK initialization instead of static fallback

  • The Claude capabilities probe now parses models from init.models returned by the SDK, building a live model catalog with effort, fastMode, and thinking options derived from SDK-provided flags.
  • When SDK discovery succeeds, the provider uses discovered models as the authoritative inventory and suppresses version-upgrade nudges; otherwise it falls back to the renamed FALLBACK_CLAUDE_MODELS static list.
  • The adapter and text generation layers now handle descriptor-less (SDK-discovered) models by forwarding raw effort and reading fastMode/thinking directly from model selection options rather than requiring catalog descriptors.
  • Models whose name ends with [1m] (e.g. opus[1m]) are assigned a 1,000,000-token context window, and xhigh effort is preserved for newer models instead of being mapped to max.
  • Behavioral Change: stale Claude models are now dropped when the refreshed snapshot is authoritative (including fallback-based warning snapshots), rather than being retained across provider merges.
📊 Macroscope summarized fc3bf5d. 4 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted

🗂️ Filtered Issues

No issues evaluated.


Note

Medium Risk
Changes core provider inventory, merge behavior, and how model options are passed into Claude sessions and text generation; mistakes could show wrong models or mis-forward effort/settings, but behavior is heavily covered by new tests.

Overview
Claude model inventory now comes from the Agent SDK initialization handshake when the probe returns models, instead of relying primarily on a version-gated static catalog. The static list remains a fallback when discovery is empty or the init probe fails.

Discovery maps each SDK ModelInfo into picker entries with effort, fast mode, and thinking options derived from the advertised flags (including ultrathink on effort selects). Provider status prefers discovered models and skips version-upgrade nags when any are present. ProviderRegistry treats Claude like OpenCode for merge semantics so successful refreshes replace stale fallback slugs and warning snapshots with the full fallback catalog do not union with old discovered IDs.

Sessions and CLI text generation forward effort, fast mode, thinking, and ultrathink correctly for SDK-only model IDs (e.g. opus[1m]) by reading selections directly when there is no static capability catalog. Context window handling treats [1m] suffixes as 1M tokens. xhighmax CLI normalization is narrowed to a specific set of older catalog models.

Reviewed by Cursor Bugbot for commit cd20057. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 5f6874c8-99a1-4fad-8a74-a1fda142066c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Jul 24, 2026
Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts
Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts
@macroscopeapp

macroscopeapp Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs human review

...

You can customize Macroscope's approvability policy. Learn more.

Comment thread apps/server/src/provider/Layers/ProviderRegistry.ts Outdated
@colonelpanic8
colonelpanic8 force-pushed the fix/discover-claude-models branch 2 times, most recently from e31cf53 to 734164f Compare July 25, 2026 00:04
colonelpanic8 and others added 3 commits July 24, 2026 20:20
A Claude capabilities probe failure degrades the snapshot to `warning`
while still shipping the complete static fallback inventory, so treating
it as a partial probe failure unioned the fallback catalog with the
previously discovered SDK slugs and showed duplicate picker entries.
Only a hard `error` (CLI missing or unrunnable) now retains stale models.

Also map the SDK's `supportsAdaptiveThinking` to the `thinking` toggle
for discovered models without effort levels, which otherwise lost the
control the static catalog gave them.

Co-Authored-By: Claude <noreply@anthropic.com>
@colonelpanic8
colonelpanic8 force-pushed the fix/discover-claude-models branch from 734164f to fc3bf5d Compare July 25, 2026 03:23

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fc3bf5d. Configure here.

Comment thread apps/server/src/textGeneration/ClaudeTextGeneration.ts
Comment thread apps/server/src/provider/Layers/ClaudeProvider.ts
@colonelpanic8
colonelpanic8 force-pushed the fix/discover-claude-models branch from cd20057 to fc3bf5d Compare July 25, 2026 05:16
const findDescriptor = (id: string) => descriptors.find((descriptor) => descriptor.id === id);
const rawEffortSelection = getModelSelectionStringOptionValue(modelSelection, "effort");
const resolvedEffort = resolveClaudeEffort(caps, rawEffortSelection);
const hasCatalogCapabilities = descriptors.length > 0;

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.

🟡 Medium textGeneration/ClaudeTextGeneration.ts:137

When a model slug returned by live SDK discovery also exists in FALLBACK_CLAUDE_MODELS, hasCatalogCapabilities becomes true even though the descriptors came from the stale fallback list rather than the live catalog. Any option the live SDK advertises for that slug that is missing from the fallback descriptors — e.g. fastMode, or a new effort value — is resolved to undefined and silently dropped from the CLI invocation; the descriptors.length > 0 check only proves a fallback entry matched, not that the live capabilities were used. The fallback-vs-live decision should be driven by the selected model's live capability source, not by whether its slug collides with the fallback catalog.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/server/src/textGeneration/ClaudeTextGeneration.ts around line 137:

When a model slug returned by live SDK discovery also exists in `FALLBACK_CLAUDE_MODELS`, `hasCatalogCapabilities` becomes `true` even though the descriptors came from the stale fallback list rather than the live catalog. Any option the live SDK advertises for that slug that is missing from the fallback descriptors — e.g. `fastMode`, or a new effort value — is resolved to `undefined` and silently dropped from the CLI invocation; the `descriptors.length > 0` check only proves a fallback entry matched, not that the live capabilities were used. The fallback-vs-live decision should be driven by the selected model's live capability source, not by whether its slug collides with the fallback catalog.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant