Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
42bafa1
feat: generalize Coder AI Gateway integration to arbitrary provider i…
ThomasK33 Aug 13, 2026
4d46a94
fix: send anthropic-version header when listing Anthropic-wire gatewa…
ThomasK33 Aug 13, 2026
3de9076
fix: keep a fresh Coder catalog unknown when any provider fails trans…
ThomasK33 Aug 13, 2026
549fa69
fix: persist authoritative provider metadata even when a fresh catalo…
ThomasK33 Aug 13, 2026
22ba4d1
fix: track catalog conclusiveness per provider (Codex round 3)
ThomasK33 Aug 13, 2026
6b6874d
fix: keep non-canonical Coder instances gateway-scoped and wire-canon…
ThomasK33 Aug 13, 2026
f53453f
fix: resolve Coder wire metadata before canonicalization (Codex round 5)
ThomasK33 Aug 13, 2026
91c6188
fix: wire-derived provider drives message prep; type-gate catalog car…
ThomasK33 Aug 13, 2026
5124d2d
fix: derive Coder gateway capability identity from instance type (Cod…
ThomasK33 Aug 13, 2026
39d76ae
fix: raw Coder identity in fallback rebuild; wire-based Anthropic con…
ThomasK33 Aug 13, 2026
a800af9
fix: retain catalog entries through inconclusive refreshes; raw capab…
ThomasK33 Aug 13, 2026
a16da9f
fix: carry stale display entries across consecutive failed refreshes;…
ThomasK33 Aug 13, 2026
42e2895
fix: wire-typed OpenAI ZDR classification; effective-route wire deriv…
ThomasK33 Aug 13, 2026
481015e
fix: coder-type-aware 1M capability gates (Codex round 12)
ThomasK33 Aug 13, 2026
dae87d9
fix: probe-path 404 keeps prior provider metadata; raw-identity 1M he…
ThomasK33 Aug 13, 2026
b2fc17d
fix: type-derived route fallback seeding; config-aware 1M retry build…
ThomasK33 Aug 13, 2026
6a4a7cd
fix: gate cache markers on disableBetaFeatures; reject unmappable cat…
ThomasK33 Aug 13, 2026
b4a9ec4
fix: raw Coder identity for fallback prompt rebuild; guard concurrent…
ThomasK33 Aug 13, 2026
a292bf5
fix: serialize catalog refresh runs in coderOauthService (Codex round…
ThomasK33 Aug 13, 2026
b76e331
fix: sessionId-lineage catalog write predicate; type-derived override…
ThomasK33 Aug 13, 2026
24faba9
fix: drop wire-mismatched provider extras for type-derived Coder over…
ThomasK33 Aug 13, 2026
4088bd4
fix: preserve raw Coder identities in usage-ledger keys (Codex round 20)
ThomasK33 Aug 13, 2026
490acf4
fix: wire identity for tool assembly; record-time metadata identity f…
ThomasK33 Aug 13, 2026
1b849a1
fix: Chat Completions wire for openai-chat Coder instances in tools a…
ThomasK33 Aug 13, 2026
79d670e
fix: canonical wire identity for passthrough fallbacks; preserve gate…
ThomasK33 Aug 13, 2026
cf94ece
fix: raw Coder identity through refusal usage recording (Codex round 24)
ThomasK33 Aug 13, 2026
928961b
fix: gate 1M beta on Anthropic wire; preserve raw Coder identity in s…
ThomasK33 Aug 14, 2026
a5990d3
fix: honor scoped mappedToModel overrides in Coder usage-ledger keys …
ThomasK33 Aug 14, 2026
94b78a7
fix: force Responses wireFormat for openai-typed Coder wires; canonic…
ThomasK33 Aug 14, 2026
4425cb7
fix: keep cross-typed Coder fallback keys gateway-scoped (Codex round…
ThomasK33 Aug 14, 2026
fd5f337
fix: keep unmappable cross-typed Coder override identities gateway-sc…
ThomasK33 Aug 14, 2026
9b1d848
fix: serialize Coder catalog refreshes across Mux processes (Codex ro…
ThomasK33 Aug 14, 2026
e1832d8
fix: carry factory coderWire snapshot through the request; type-deriv…
ThomasK33 Aug 14, 2026
bf6bb22
fix: create Coder models from the same providers-config snapshot as t…
ThomasK33 Aug 14, 2026
6fbd84d
fix: one pinned providers-config snapshot per request; key CostsTab l…
ThomasK33 Aug 14, 2026
b43dba4
fix: key usage ledger by pinned/persisted metadata identity for Coder…
ThomasK33 Aug 14, 2026
85173c1
fix: carry the pinned providers-config snapshot into StreamManager (C…
ThomasK33 Aug 14, 2026
943c307
fix: pin gateway identities through startup recovery, frontend usage,…
ThomasK33 Aug 14, 2026
18b5035
fix: keep unmappable canonical-named Coder routes gateway-scoped
ThomasK33 Aug 14, 2026
2a56479
fix: reject disconnected unmappable Coder routes; pin instance for fa…
ThomasK33 Aug 14, 2026
676eec2
fix: build options/headers from the effective route when Coder routin…
ThomasK33 Aug 14, 2026
2953f0d
fix: pin live Coder usage identity via stream-start metadataModel
ThomasK33 Aug 14, 2026
6c5e32c
fix: preserve gateway identity in persisted task model settings
ThomasK33 Aug 14, 2026
eee2fbf
fix: gateway-preserving maintenance sends; final thinking clamp from …
ThomasK33 Aug 14, 2026
79b9542
fix: pin overrides raw config and advisor pricing identity to creatio…
ThomasK33 Aug 14, 2026
928a80e
fix: single-snapshot advisor model creation; pinned identity for timi…
ThomasK33 Aug 14, 2026
363813b
fix: fallback thinking from pinned snapshot; compaction summary keeps…
ThomasK33 Aug 14, 2026
e950c37
fix: advisor options from wire-resolved identity; gateway-preserving …
ThomasK33 Aug 14, 2026
c50a0fc
fix: pin headless coder usage identities; gateway-scoped thinking-flo…
ThomasK33 Aug 14, 2026
8ed2774
Round 50: legacy thinking-floor key fallback + effective-route headle…
ThomasK33 Aug 14, 2026
dcfd4b6
Round 51: preserve gateway identity in hidden-model preferences
ThomasK33 Aug 14, 2026
f4fd662
Round 52: gateway-preserving selection equality in handleModelChange
ThomasK33 Aug 14, 2026
ade8fa8
Round 53: coder-aware selection tracking + metadata-aware ModelRow
ThomasK33 Aug 14, 2026
74d2b1b
Round 54: observable Coder refresh failures + raw-first compaction su…
ThomasK33 Aug 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 26 additions & 6 deletions docs/config/providers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,13 @@ Operational notes:
### Coder (Login with Coder)

The Coder provider routes requests through a [Coder](https://coder.com) deployment's
AI Bridge (`/api/v2/aibridge`), so usage is authenticated, governed, and audited by the
AI Gateway (`/api/v2/aibridge`), so usage is authenticated, governed, and audited by the
deployment instead of a personal API key.

Deployment prerequisites (admin-side):

- The OAuth2 provider experiment: start `coderd` with `--experiments=oauth2` (or `CODER_EXPERIMENTS=oauth2`)
- AI Bridge entitlement and `--aibridge-enabled`, with at least one upstream (Anthropic and/or OpenAI) configured
- AI Gateway entitlement and `--aibridge-enabled`, with at least one provider configured

To connect:

Expand All @@ -202,10 +202,30 @@ To connect:
Mux registers itself as an OAuth2 client on the deployment (RFC 7591 dynamic client
registration), completes an authorization-code + PKCE flow, and stores the resulting tokens
in `~/.mux/providers.jsonc`. Tokens refresh automatically; **Disconnect** revokes and clears
them. After login, Mux lists models from the bridge's upstream catalogs as
`coder:anthropic/<model>` and `coder:openai/<model>`; you can also add model IDs manually
under the provider's model list. Manual edits are preserved across re-logins and catalog
refreshes: added entries stay listed, and removed catalog entries stay removed.
them.

After login, Mux discovers the deployment's configured AI Gateway providers and their model
catalogs, listing models as `coder:<provider>/<model>` (e.g. `coder:anthropic/<model>`,
`coder:my-openai/<model>`). Each provider's type (anthropic, openai, bedrock,
openai-compat, ...) decides the wire protocol Mux speaks to its gateway route. Use the
**Refresh models** button (or the "Settings: Refresh Coder Models" command) to re-discover
without a re-login. You can also add model IDs manually under the provider's model list;
manual edits are preserved across re-logins and catalog refreshes: added entries stay
listed, and removed catalog entries stay removed.

Listing the deployment's providers requires an admin-level API on some deployments; when it
is unavailable Mux probes the default provider names instead. If your deployment uses
custom-named provider instances that Mux cannot discover, declare them by hand in
`~/.mux/providers.jsonc`:

```jsonc
{
"coder": {
"additionalProviders": [{ "name": "llm-proxy", "type": "openai-compat" }],
"models": ["llm-proxy/llama-3.3-70b"],
},
}
```

Login is available from the desktop app or a locally hosted Mux server. On a remote Mux
server the OAuth callback cannot reach your browser's machine (Coder does not support the
Expand Down
7 changes: 5 additions & 2 deletions src/browser/components/Toggle1MContext/Toggle1MContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { useProviderOptions } from "@/browser/hooks/useProviderOptions";
import { cn } from "@/common/lib/utils";
import { supports1MContext } from "@/common/utils/ai/models";
import { useProvidersConfig } from "@/browser/hooks/useProvidersConfig";

interface Toggle1MContextProps {
/** Model ID to check/toggle 1M context for */
Expand All @@ -17,10 +18,12 @@ interface Toggle1MContextProps {
*/
export const Toggle1MContext: React.FC<Toggle1MContextProps> = (props) => {
const { has1MContext, toggle1MContext } = useProviderOptions();
const { config: providersConfig } = useProvidersConfig();

// 1M context is a runtime model capability, gated on the runtime model —
// not inherited through "Treat as" model mapping.
if (!supports1MContext(props.model)) return null;
// not inherited through "Treat as" model mapping. Coder gateway instances
// resolve through their instance type (the gateway is a transparent proxy).
if (!supports1MContext(props.model, providersConfig)) return null;

const label = props.label ?? "1M context";
const enabled = has1MContext(props.model);
Expand Down
4 changes: 3 additions & 1 deletion src/browser/contexts/ProviderOptionsContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "@/common/constants/storage";
import type { MuxProviderOptions } from "@/common/types/providerOptions";
import { supports1MContext } from "@/common/utils/ai/models";
import { useProvidersConfig } from "@/browser/hooks/useProvidersConfig";
import { KNOWN_MODELS } from "@/common/constants/knownModels";

interface ProviderOptionsContextType {
Expand Down Expand Up @@ -54,6 +55,7 @@ function migrateGlobalToPerModel(
}

export function ProviderOptionsProvider({ children }: { children: React.ReactNode }) {
const { config: providersConfig } = useProvidersConfig();
const [anthropicOptions, setAnthropicOptions] = usePersistedState<
MuxProviderOptions["anthropic"]
>(PROVIDER_OPTIONS_ANTHROPIC_KEY, {}, { listener: true });
Expand Down Expand Up @@ -81,7 +83,7 @@ export function ProviderOptionsProvider({ children }: { children: React.ReactNod
return true;
}

return supports1MContext(modelId) && anthropicOptions?.use1MContext === true;
return supports1MContext(modelId, providersConfig) && anthropicOptions?.use1MContext === true;
};

const toggle1MContext = (modelId: string): void => {
Expand Down
52 changes: 52 additions & 0 deletions src/browser/contexts/ThinkingContext.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,58 @@ describe("ThinkingContext", () => {
}
});

test("setting thinking preserves an explicit Coder gateway model identity", async () => {
// A cross-typed instance ({name: "openai", type: "anthropic"}) makes
// coder:openai/<claude> a valid gateway selection. Changing the thinking
// level must persist that identity intact — normalizeToCanonical would
// rewrite it to openai:<claude> from the name alone and silently reroute
// the workspace to direct OpenAI.
const workspaceId = "ws-set-thinking-coder-model";
const coderModel = "coder:openai/claude-opus-4-5";
const updateAgentAISettings = mock<
(args: WorkspaceUpdateAgentAISettingsArgs) => Promise<WorkspaceUpdateAgentAISettingsResult>
>(() =>
Promise.resolve({
success: true as const,
data: undefined,
})
);
currentClientMock = {
workspace: { updateAgentAISettings },
};

setWorkspaceMetadata(
createWorkspaceMetadata({
id: workspaceId,
aiSettings: { model: coderModel, thinkingLevel: "high" },
})
);

const view = renderWithWorkspaceMetadata({
workspaceId,
modelOverride: null,
children: (
<ThinkingProvider workspaceId={workspaceId}>
<ThinkingSetterComponent />
</ThinkingProvider>
),
});

const button = await view.findByTestId("set-thinking-medium", undefined, METADATA_WAIT_OPTIONS);
act(() => {
button.click();
});

const expectedSettings = {
model: coderModel,
thinkingLevel: "medium" as const,
reasoningMode: "standard" as const,
};
await waitFor(() => {
expect(readWorkspaceAISettingsCache(workspaceId).exec).toEqual(expectedSettings);
}, METADATA_WAIT_OPTIONS);
});

test("self-heals corrupt persisted reasoningMode to standard but keeps valid pro", async () => {
// Corrupt persisted values (e.g. from a future downgrade) must coerce to
// "standard" instead of flowing into SendMessageOptionsSchema and bricking sends.
Expand Down
11 changes: 9 additions & 2 deletions src/browser/contexts/ThinkingContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
GLOBAL_SCOPE_ID,
} from "@/common/constants/storage";
import { getDefaultModel } from "@/browser/hooks/useModelsFromSettings";
import { normalizeToCanonical } from "@/common/utils/ai/models";
import { normalizeSelectedModel, normalizeToCanonical } from "@/common/utils/ai/models";
import { enforceThinkingPolicy, getAvailableThinkingLevels } from "@/common/utils/thinking/policy";
import { useMinThinkingLevels } from "@/browser/hooks/useMinThinkingLevels";
import { useProvidersConfig } from "@/browser/hooks/useProvidersConfig";
Expand Down Expand Up @@ -69,7 +69,14 @@ function getModelForThinkingUpdate(
): string {
const persistedModel = readPersistedState<string | undefined>(getModelKey(scopeId), undefined);
// Prefer localStorage, then metadata, then the default model to avoid clobbering startup metadata.
return normalizeToCanonical(persistedModel ?? metadataModel ?? fallbackModel);
// normalizeSelectedModel (not normalizeToCanonical): this value is persisted
// back via persistAgentAiSettings, and explicit gateway identities must
// survive — normalizeToCanonical rewrites coder:openai/<claude> (a valid
// cross-typed instance) to openai:<claude> from the name alone, so merely
// changing the thinking level would silently reroute the workspace to
// direct OpenAI. Thinking policy lookups resolve gateway-scoped strings
// through resolveModelForMetadata, so capability behavior is unchanged.
return normalizeSelectedModel(persistedModel ?? metadataModel ?? fallbackModel);
}

export const ThinkingProvider: React.FC<ThinkingProviderProps> = (props) => {
Expand Down
16 changes: 14 additions & 2 deletions src/browser/features/RightSidebar/CostsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import {
getTotalCost,
type ChatUsageDisplay,
} from "@/common/utils/tokens/usageAggregator";
import { normalizeToCanonical, formatModelStringForDisplay } from "@/common/utils/ai/models";
import { formatModelStringForDisplay } from "@/common/utils/ai/models";
import { normalizeUsageModelKey } from "@/common/utils/providers/modelEntries";
import { useProvidersConfig } from "@/browser/hooks/useProvidersConfig";
import { usePersistedState } from "@/browser/hooks/usePersistedState";
import { ToggleGroup, type ToggleOption } from "@/browser/components/ToggleGroup/ToggleGroup";
import { TOKEN_COMPONENT_COLORS, formatTokens } from "@/common/utils/tokens/tokenMeterUtils";
Expand All @@ -26,6 +28,7 @@ interface CostsTabProps {

const CostsTabComponent: React.FC<CostsTabProps> = ({ workspaceId }) => {
const usage = useWorkspaceUsage(workspaceId);
const { config: providersConfig } = useProvidersConfig();
const [viewMode, setViewMode] = usePersistedState<ViewMode>("costsTab:viewMode", "session");

// Session usage for cost calculation
Expand All @@ -44,7 +47,16 @@ const CostsTabComponent: React.FC<CostsTabProps> = ({ workspaceId }) => {
const merged = new Map<string, ChatUsageDisplay>(Object.entries(usage.sessionByModel ?? {}));
const liveModel = usage.liveCostUsage?.model;
if (usage.liveCostUsage && liveModel) {
const key = normalizeToCanonical(liveModel);
// Same ledger key as the backend and WorkspaceStore deltas: live Coder
// usage keys on the stream's request-pinned metadata identity
// (liveMetadataModel) — re-resolving the raw coder:<instance>/<model>
// against a mid-stream-refreshed providers config could re-key or
// split the row from the backend's bucket. Non-Coder models keep the
// canonical normalizeUsageModelKey.
const key =
liveModel.startsWith("coder:") && usage.liveMetadataModel
? usage.liveMetadataModel
: normalizeUsageModelKey(liveModel, providersConfig);
const existing = merged.get(key);
merged.set(
key,
Expand Down
24 changes: 16 additions & 8 deletions src/browser/features/Settings/Sections/ModelFallbacksEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@ import {
} from "@/browser/components/SelectPrimitive/SelectPrimitive";
import { useModelFallbacks } from "@/browser/hooks/useModelFallbacks";
import { useModelsFromSettings } from "@/browser/hooks/useModelsFromSettings";
import { MODEL_FALLBACK_CHAIN_LIMIT } from "@/common/utils/ai/modelFallbacks";
import { normalizeToCanonical } from "@/common/utils/ai/models";
import { useProvidersConfig } from "@/browser/hooks/useProvidersConfig";
import {
MODEL_FALLBACK_CHAIN_LIMIT,
normalizeFallbackModelKey,
} from "@/common/utils/ai/modelFallbacks";

const SELECT_TRIGGER_CLASS =
"border-border-medium bg-background-secondary hover:bg-hover h-7 w-64 cursor-pointer rounded-md border px-2 text-xs transition-colors";
Expand All @@ -28,16 +31,20 @@ const SELECT_TRIGGER_CLASS =
export function ModelFallbacksEditor() {
const { modelFallbacks, setFallbackChain } = useModelFallbacks();
const { models } = useModelsFromSettings();
const { config: providersConfig } = useProvidersConfig();
// Draft source model for a chain being created (entries with empty chains
// are never persisted, so the first fallback pick materializes the entry).
const [draftSource, setDraftSource] = useState<string | null>(null);

const entries = Object.entries(modelFallbacks).sort(([a], [b]) => a.localeCompare(b));
const configuredSources = new Set(entries.map(([source]) => source));
// Settings can list aliases that canonicalize to the same model (e.g. a
// gateway-prefixed copy of a built-in). Dedupe via canonical form so
// SelectItem values stay unique; chains store canonical strings anyway.
const modelCandidates = Array.from(new Set(models.map((model) => normalizeToCanonical(model))));
// gateway-prefixed copy of a built-in). Dedupe via the metadata-aware
// fallback key so SelectItem values stay unique while cross-typed Coder
// instances keep a chain distinct from the direct provider's.
const modelCandidates = Array.from(
new Set(models.map((model) => normalizeFallbackModelKey(model, providersConfig)))
);
const sourceCandidates = modelCandidates.filter((model) => !configuredSources.has(model));

const chainFor = (source: string): string[] => modelFallbacks[source]?.models ?? [];
Expand Down Expand Up @@ -167,10 +174,11 @@ export function ModelFallbacksEditor() {

{entries.map(([source, entry]) => renderChainRow(source, entry.models))}

{draftSource !== null && !configuredSources.has(normalizeToCanonical(draftSource)) ? (
{draftSource !== null &&
!configuredSources.has(normalizeFallbackModelKey(draftSource, providersConfig)) ? (
renderChainRow(
normalizeToCanonical(draftSource),
chainFor(normalizeToCanonical(draftSource))
normalizeFallbackModelKey(draftSource, providersConfig),
chainFor(normalizeFallbackModelKey(draftSource, providersConfig))
)
) : (
<div className="flex items-center gap-2">
Expand Down
19 changes: 14 additions & 5 deletions src/browser/features/Settings/Sections/ModelRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import { ProviderIcon, ProviderWithIcon } from "@/browser/components/ProviderIco
import { formatModelDisplayName } from "@/common/utils/ai/modelDisplay";
import { cn } from "@/common/lib/utils";
import type { AvailableRoute } from "@/common/routing";
import { getModelStats, type ModelStats } from "@/common/utils/tokens/modelStats";
import { getModelStatsResolved, type ModelStats } from "@/common/utils/tokens/modelStats";
import type { ProvidersConfigMap } from "@/common/orpc/types";
import { getThinkingOptionLabel, type ThinkingLevel } from "@/common/types/thinking";
import {
getAvailableThinkingLevels,
Expand Down Expand Up @@ -222,10 +223,17 @@ export interface ModelRowProps {
onToggle1MContext?: () => void;
/** Toggle visibility in model selector */
onToggleVisibility?: () => void;
/**
* Providers config for metadata-aware identity resolution. Coder gateway
* rows (coder:<instance>/<model>) derive pricing/context/thinking data from
* the instance's TYPE, which arbitrary instance names cannot convey.
*/
providersConfig?: ProvidersConfigMap | null;
}

export function ModelRow(props: ModelRowProps) {
const stats = getModelStats(props.mappedToModel ?? props.fullId);
const providersConfig = props.providersConfig ?? null;
const stats = getModelStatsResolved(props.mappedToModel ?? props.fullId, providersConfig);

const contextBaseTokens = props.customContextWindowTokens ?? stats?.max_input_tokens ?? null;
const mappedProvider = props.mappedToModel ? props.mappedToModel.split(":")[0] || null : null;
Expand All @@ -251,14 +259,15 @@ export function ModelRow(props: ModelRowProps) {
// non-reasoning models and single-level models (e.g. gpt-5-pro) keep the legacy behavior
// with no selector. The dropdown lists the model's full capability so users can pick any
// floor, including off/low.
const thinkingCapability = getThinkingPolicyForModel(props.fullId);
const thinkingCapability = getThinkingPolicyForModel(props.fullId, providersConfig);
const supportsMinThinking =
hasExplicitThinkingPolicy(props.fullId) && thinkingCapability.length > 1;
hasExplicitThinkingPolicy(props.fullId, providersConfig) && thinkingCapability.length > 1;
// The selected value is the effective floor shown as a plain level (no "Default" wording).
// It's always one of the capability options since available levels are a capability subset.
const minThinkingFloorLevel = getAvailableThinkingLevels(
props.fullId,
resolveMinimumThinkingLevel(props.fullId, props.minThinkingLevel)
resolveMinimumThinkingLevel(props.fullId, props.minThinkingLevel, providersConfig),
providersConfig
)[0];

// Editing mode - render as a full-width row
Expand Down
6 changes: 4 additions & 2 deletions src/browser/features/Settings/Sections/ModelsSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -528,10 +528,11 @@ export function ModelsSection() {
minThinking.setMinThinkingLevel(model.fullId, level)
}
onToggle1MContext={
supports1MContext(model.fullId)
supports1MContext(model.fullId, config)
? () => toggle1MContext(model.fullId)
Comment thread
ThomasK33 marked this conversation as resolved.
: undefined
}
providersConfig={config}
/>
);
})}
Expand Down Expand Up @@ -577,10 +578,11 @@ export function ModelsSection() {
minThinking.setMinThinkingLevel(model.fullId, level)
}
onToggle1MContext={
supports1MContext(model.fullId)
supports1MContext(model.fullId, config)
? () => toggle1MContext(model.fullId)
: undefined
}
providersConfig={config}
/>
))}
</tbody>
Expand Down
Loading
Loading