Before submitting
Area
packages/contracts or packages/shared
Problem or use case
When creating a new thread, the provider always defaults to Codex. Users who primarily use Claude have to manually switch the provider every time they start a new thread. This is especially noticeable in self-hosted/Coder workspace setups where Claude is the preferred provider.
The fallback is currently hardcoded:
// apps/web/src/components/ChatView.tsx#L603
const selectedProvider: ProviderKind = lockedProvider ?? selectedProviderByThreadId ?? "codex";
There is a DEFAULT_PROVIDER_KIND constant in packages/contracts/src/orchestration.ts, but it isn't referenced by the UI — the "codex" string is inlined directly.
Proposed solution
Allow users to configure the default provider, so new threads start with their preferred provider instead of always falling back to Codex. A few possible approaches:
- App setting — add a
defaultProvider field to AppSettings (similar to defaultThreadEnvMode) and use it as the fallback in ChatView.tsx instead of the hardcoded "codex".
- Infer from project model — use the existing
inferProviderForModel() from packages/shared/src/model.ts to derive the provider from the project's defaultModel. If a project's default model is claude-sonnet-4-6, the provider should resolve to claudeAgent automatically.
- Wire up the existing constant — replace the inlined
"codex" fallbacks with DEFAULT_PROVIDER_KIND from contracts, then make that configurable.
Why this matters
Users who primarily work with Claude have to manually switch the provider on every new thread. This adds friction, especially for teams that have standardized on Claude as their provider. It would make T3 Code feel more provider-neutral.
Smallest useful scope
An app-level setting for default provider (option 1) would solve the immediate problem. Even just wiring up inferProviderForModel on the project's defaultModel (option 2) would cover the most common case without any new UI.
Alternatives considered
- Manually switching the provider each time a new thread is created (current workaround).
- Setting the project's
defaultModel to a Claude model — but this only affects model resolution, not the provider picker, since the provider is resolved before the model.
Risks or tradeoffs
Minimal risk — the fallback behavior for users who don't configure this would remain unchanged ("codex").
Examples or references
Contribution
Before submitting
Area
packages/contracts or packages/shared
Problem or use case
When creating a new thread, the provider always defaults to Codex. Users who primarily use Claude have to manually switch the provider every time they start a new thread. This is especially noticeable in self-hosted/Coder workspace setups where Claude is the preferred provider.
The fallback is currently hardcoded:
There is a
DEFAULT_PROVIDER_KINDconstant inpackages/contracts/src/orchestration.ts, but it isn't referenced by the UI — the"codex"string is inlined directly.Proposed solution
Allow users to configure the default provider, so new threads start with their preferred provider instead of always falling back to Codex. A few possible approaches:
defaultProviderfield toAppSettings(similar todefaultThreadEnvMode) and use it as the fallback inChatView.tsxinstead of the hardcoded"codex".inferProviderForModel()frompackages/shared/src/model.tsto derive the provider from the project'sdefaultModel. If a project's default model isclaude-sonnet-4-6, the provider should resolve toclaudeAgentautomatically."codex"fallbacks withDEFAULT_PROVIDER_KINDfrom contracts, then make that configurable.Why this matters
Users who primarily work with Claude have to manually switch the provider on every new thread. This adds friction, especially for teams that have standardized on Claude as their provider. It would make T3 Code feel more provider-neutral.
Smallest useful scope
An app-level setting for default provider (option 1) would solve the immediate problem. Even just wiring up
inferProviderForModelon the project'sdefaultModel(option 2) would cover the most common case without any new UI.Alternatives considered
defaultModelto a Claude model — but this only affects model resolution, not the provider picker, since the provider is resolved before the model.Risks or tradeoffs
Minimal risk — the fallback behavior for users who don't configure this would remain unchanged (
"codex").Examples or references
DEFAULT_PROVIDER_KINDinpackages/contracts/src/orchestration.tsinferProviderForModel()inpackages/shared/src/model.tsapps/web/src/components/ChatView.tsx#L603Contribution