[Bug]: Custom Claude model effort and Thinking selections are saved but dropped at runtime#16672

opened23d agobyKKevinXC5

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Create a custom provider instance using the Claude driver. In this setup, Magpie creates the instance and exposes codex/gpt-6.1-sol[1m], which is not in T3's bundled Claude model catalog.
  2. Declare capabilities.optionDescriptors for the custom model: an effort select (low/medium/high/xhigh/max) and a boolean thinking option. Both controls appear in the composer.
  3. Select effort High, toggle Thinking, and confirm the thread configuration saves the selected options.
  4. Start a fresh Claude CLI process and send a message. Inspect SDK query.open, the CLI arguments, and the gateway's request records.
  5. No SDK effort or CLI --effort is passed. If Claude settings specify effortLevel: "medium" for this model, the gateway receives medium even though T3 displays High.
  6. The same compilation path drops thinking=false: it does not produce alwaysThinkingEnabled:false, and the default query construction still enables adaptive thinking.

Related: #4192 / discussion #6793 concerned a missing Reasoning control. This report concerns custom models whose controls are already visible and whose choices are saved, but not applied at runtime.

Expected behavior

The Claude adapter should compile ModelSelection against the current provider instance's custom model capabilities. The selected effort should reach SDK effort / CLI --effort, and Thinking true/false should be applied using the SDK's supported options.

These options should also participate in queryIdentity, so an existing process is not reused with settings that differ from the user's selection. Preserve compatibility mappings for built-in models.

Actual behavior

The UI and thread configuration retain the selections, but the runtime compiler uses the bundled catalog. An unknown custom model therefore gets empty capabilities: effort resolves to undefined, and the Thinking option is ignored.

Evidence: effort was verified using thread configuration, SDK launch logs, CLI arguments, and gateway records. The Thinking finding is based on the runtime code path; I have not separately captured the upstream wire body for thinking=false.

Suspected cause

  • compileClaudeModelSelection(selection, catalog = BUNDLED_CLAUDE_MODEL_CATALOG) looks up capabilities in the supplied catalog.
  • ClaudeAdapterV2.makeClaudeQueryOptions calls compileClaudeModelSelection(input.modelSelection) without an instance-scoped catalog.
  • For this custom model, the effort descriptor is missing and supportsBoolean("thinking") is false, so neither SDK effort nor alwaysThinkingEnabled is generated.
  • requestThinkingSummaries checks compiledSelection.settings.alwaysThinkingEnabled !== false, and the default branch supplies adaptive thinking.
  • Other adapter calls used to construct queryIdentity also compile against the default catalog.

Code:

Please check instance-scoped catalog propagation and add regression coverage for custom model effort=high, thinking=false, and their query identities.

Impact

Major degradation or frequent failure: runtime reasoning settings differ from the visible selections, making quality and usage difficult to control.

Version or commit

0.0.46-nightly.20261006.2752. The inspected main branch also contains these calls without a custom catalog.

Environment

macOS / Apple Silicon; T3 Code Nightly desktop; Claude Code 2.1.292; Magpie v0.1.1098; custom claudeAgent provider; model codex/gpt-6.1-sol[1m].

Logs or stack traces

text
1Saved selection: effort=high, thinking=true
2SDK query.open settings: {"showThinkingSummaries":true}
3No effort or alwaysThinkingEnabled field.
4CLI arguments include --thinking adaptive --model codex/gpt-6.1-sol[1m]
5No --effort argument.
6With modelSettings effortLevel=medium, the gateway receives medium.

Workaround

Configure the model's effortLevel in Claude settings and ensure the CLI reads them. This controls the actual effort, but T3's per-thread picker still does not override it.

An explicit provider launchArgs effort or process environment override may be another fixed-effort workaround; only the settings workaround was verified here.

Synced from GitHub

Fast mode is affected by the same root cause: a custom model's fastMode descriptor is dropped when makeClaudeQueryOptions compiles against the bundled catalog (closed duplicate #16755). Once #16583 passes the scoped catalog, settings.fastMode should be produced; it would be worth including a custom-model fastMode: true regression case. One open question remains outside T3: whether Claude Code then forwards fast mode for a non-Claude model ID through an Anthropic-compatible proxy. I can test that end-to-end after #16583 lands.

Synced from GitHub

Added the custom-model fastMode: true case to #16583 in 4fcf878142. The test fails with settings missing fastMode when the adapter compiles against the bundled catalog, and passes with the fix. Thanks for offering to test the proxy path end to end once it lands.

Reproduced on 74541bab17 through an isolated dev server: a saved custom Thinking selection was omitted from the Claude SDK settings at launch, while an explicit effort was preserved. #22792 applies the selection and replaces the query on toggles; explicit effort remains preserved.