diff --git a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/model-selector.tsx b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/model-selector.tsx
index 871225d7ea5..83a7f75c1f1 100644
--- a/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/model-selector.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/home/components/user-input/components/model-selector.tsx
@@ -45,7 +45,7 @@ export function ModelSelector() {
{ effort: effortChoice ?? undefined, modelSelection: selection },
advanced
)
- const options = advanced
+ const options = modelSelection
? mothershipEffortOptions(modelSelection.model)
: MOTHERSHIP_SIMPLE_EFFORT_OPTIONS
const setEffort = (choice: MothershipEffort) => {
@@ -59,13 +59,10 @@ export function ModelSelector() {
}, [chatId])
const effortLabel = options.find((option) => option.value === effort)?.label ?? effort
- const modelLabel =
- MOTHERSHIP_MODEL_OPTIONS.find((option) => option.value === modelSelection.model)?.label ??
- modelSelection.model
return (
- {advanced && (
+ {modelSelection && (
<>
{modelSelection.model !== 'claude-opus-5-5' && (
option.value === modelSelection.model)
+ ?.label ?? modelSelection.model
+ }
icon={Sparkles}
showChevron
/>
diff --git a/apps/sim/lib/mothership/chat/post.test.ts b/apps/sim/lib/mothership/chat/post.test.ts
index 86dcab8c45f..9e804f6fca8 100644
--- a/apps/sim/lib/mothership/chat/post.test.ts
+++ b/apps/sim/lib/mothership/chat/post.test.ts
@@ -816,7 +816,7 @@ describe('handleUnifiedChatPost', () => {
['low', 'low'],
['none', 'high'],
])(
- 'enforces the default model and effort range on submitted %s effort',
+ 'leaves the model to the worker and enforces the effort range on submitted %s effort',
async (effort, expected) => {
flags.models.mockResolvedValue(false)
const response = await handleUnifiedChatPost(
@@ -831,12 +831,9 @@ describe('handleUnifiedChatPost', () => {
})
)
expect(response.status).toBe(200)
- expect(buildCopilotRequestPayload).toHaveBeenCalledWith(
- expect.objectContaining({
- effort: expected,
- modelSelection: { model: 'gpt-6-astra', fastMode: false },
- })
- )
+ const { requestPayload } = createSSEStream.mock.lastCall?.[0] ?? {}
+ expect(requestPayload?.effort).toBe(expected)
+ expect(JSON.stringify(requestPayload)).not.toContain('modelSelection')
}
)
diff --git a/apps/sim/lib/mothership/model-options.ts b/apps/sim/lib/mothership/model-options.ts
index b4d26c75570..aff834b7ab1 100644
--- a/apps/sim/lib/mothership/model-options.ts
+++ b/apps/sim/lib/mothership/model-options.ts
@@ -38,22 +38,29 @@ export function mothershipEffortOptions(model: ModelSelection['model']) {
: MOTHERSHIP_EFFORT_OPTIONS
}
-/** Shared by the visible controls, send path and server admission so hidden preferences cannot leak. */
+/**
+ * Shared by the visible controls, send path and server admission so hidden preferences cannot leak.
+ * Without the model picker no selection is sent, so the worker routes every model role itself.
+ */
export function resolveMothershipModelSettings(
settings: { effort?: MothershipEffort; modelSelection?: ModelSelection },
advanced: boolean
-): { effort: MothershipEffort; modelSelection: ModelSelection } {
+): { effort: MothershipEffort; modelSelection: ModelSelection | undefined } {
let effort = settings.effort ?? DEFAULT_MOTHERSHIP_EFFORT
if (!advanced) {
if (effort === 'none') effort = DEFAULT_MOTHERSHIP_EFFORT
if (effort === 'max') effort = 'xhigh'
- return { effort, modelSelection: { model: 'gpt-6-astra', fastMode: false } }
+ return { effort, modelSelection: undefined }
}
- const stored = settings.modelSelection ?? { model: 'gpt-6-astra', fastMode: false }
+ const modelSelection = normalizeModelSelection(
+ settings.modelSelection ?? { model: 'gpt-6-astra', fastMode: false }
+ )
+ if (effort === 'none' && modelSelection.model !== 'gpt-6-sol') effort = DEFAULT_MOTHERSHIP_EFFORT
+ return { effort, modelSelection }
+}
+
+/** A stored pick on the current catalog: Opus 5 reads as Opus 5.5, which has no Fast mode. */
+export function normalizeModelSelection(stored: ModelSelection): ModelSelection {
const model = stored.model === 'claude-opus-5' ? 'claude-opus-5-5' : stored.model
- if (effort === 'none' && model !== 'gpt-6-sol') effort = DEFAULT_MOTHERSHIP_EFFORT
- return {
- effort,
- modelSelection: { model, fastMode: model === 'claude-opus-5-5' ? false : stored.fastMode },
- }
+ return { model, fastMode: model === 'claude-opus-5-5' ? false : stored.fastMode }
}
diff --git a/apps/sim/stores/mothership-effort/store.ts b/apps/sim/stores/mothership-effort/store.ts
index a885b641931..0ec4b53977b 100644
--- a/apps/sim/stores/mothership-effort/store.ts
+++ b/apps/sim/stores/mothership-effort/store.ts
@@ -2,10 +2,7 @@ import { omit, toRecord } from '@sim/utils/object'
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
import { type ModelSelection, ModelSelectionSchema } from '@/lib/mothership/generated/protocol'
-import {
- type MothershipEffort,
- resolveMothershipModelSettings,
-} from '@/lib/mothership/model-options'
+import { type MothershipEffort, normalizeModelSelection } from '@/lib/mothership/model-options'
/** A chat's effort pick and the token that tells it apart from other picks of the same value. */
interface ChatEffortPick {
@@ -52,7 +49,7 @@ let lastChatEffortPick = 0
function withModelSelection(
modelSelection: ModelSelection
): Pick {
- return { modelSelection: resolveMothershipModelSettings({ modelSelection }, true).modelSelection }
+ return { modelSelection: normalizeModelSelection(modelSelection) }
}
export const useMothershipEffortStore = create()(