From 75b13e33063a474610bb988ed853f9f2700bec65 Mon Sep 17 00:00:00 2001 From: KyeMoon123 Date: Wed, 19 Aug 2026 23:42:39 +1000 Subject: [PATCH] fix(web): let new threads honor the project's default model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New threads were seeded from the global "sticky" last-used model (applyStickyState) and only fell back to the project's configured defaultModelSelection when no sticky value existed at all — which in practice only happens on a user's very first thread ever. As a result, the project setting "New threads in this project start with this model" was effectively never applied once any thread anywhere had already picked a model. Apply the project default whenever there's no carried selection from a currently-viewed thread/draft to take priority instead, across all three new-thread paths: minting a genuinely fresh draft, reusing a stored-but-empty draft, and reusing the empty draft already open. --- apps/web/src/hooks/useHandleNewThread.ts | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/apps/web/src/hooks/useHandleNewThread.ts b/apps/web/src/hooks/useHandleNewThread.ts index 64176c0873a7..e5987febd3ec 100644 --- a/apps/web/src/hooks/useHandleNewThread.ts +++ b/apps/web/src/hooks/useHandleNewThread.ts @@ -280,6 +280,14 @@ export function useNewThreadHandler() { setModelSelection(emptyStoredDraftThread.draftId, carryModelSelection, { replaceOptions: true, }); + } else if (project?.defaultModelSelection) { + // Reusing an empty draft with nothing to carry a selection + // from: the project's configured default is a deliberate + // per-project choice and takes priority over whatever model + // this draft happened to be left on. + setModelSelection(emptyStoredDraftThread.draftId, project.defaultModelSelection, { + replaceOptions: true, + }); } } // The workspace context must also ride along here: when projectRef @@ -345,6 +353,15 @@ export function useNewThreadHandler() { interactionMode: latestActiveDraftThread.interactionMode, ...pickExplicitWorkspaceOptions(options), }); + if (!carryModelSelection && project?.defaultModelSelection) { + // This empty draft (the one already open) has no model selection + // of its own yet: the project's configured default is a + // deliberate per-project choice and takes priority over whatever + // model this draft happened to be left on. + setModelSelection(currentRouteTarget.draftId, project.defaultModelSelection, { + replaceOptions: true, + }); + } return Promise.resolve({ draftId: currentRouteTarget.draftId, threadId: latestActiveDraftThread.threadId, @@ -416,6 +433,12 @@ export function useNewThreadHandler() { // complete snapshot — absent options mean "no options", not "keep // whatever sticky state just wrote". setModelSelection(draftId, carryModelSelection, { replaceOptions: true }); + } else if (project?.defaultModelSelection) { + // A brand new thread with nothing to carry a selection from: the + // project's configured default is a deliberate per-project choice + // and takes priority over the sticky map's cross-project "last + // used model". + setModelSelection(draftId, project.defaultModelSelection, { replaceOptions: true }); } carryComposerContentTo(draftId);