Skip to content

[Feature]: Configurable default provider for new threads #1394

@luizstacio

Description

@luizstacio

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I am describing a concrete problem or use case, not just a vague idea.

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:

  1. 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".
  2. 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.
  3. 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

  • I would be open to helping implement this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions