Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 14 additions & 0 deletions apps/web/src/composerDraftStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1754,6 +1754,7 @@ describe("composerDraftStore modelSelection", () => {
).toEqual(
expect.objectContaining({
instanceId: CODEX_SECONDARY_INSTANCE,
model: "gpt-5-codex",
options: [{ id: "reasoningEffort", value: "low" }],
}),
);
Expand All @@ -1770,6 +1771,19 @@ describe("composerDraftStore modelSelection", () => {
options: [{ id: "reasoningEffort", value: "low" }],
}),
);
expect(
useComposerDraftStore.getState().stickyOptionsByModelByProvider[CODEX_SECONDARY_INSTANCE],
).toEqual({ "gpt-5-codex": [{ id: "reasoningEffort", value: "low" }] });

// A custom slug that matches a Codex alias stays exact; the picker already resolved it.
store.setModelSelection(threadRef, createModelSelection(CODEX_SECONDARY_INSTANCE, "gpt-5.3"), {
explicit: true,
replaceOptions: true,
});
expect(
draftFor(threadId, TEST_ENVIRONMENT_ID)?.modelSelectionByProvider[CODEX_SECONDARY_INSTANCE]
?.model,
).toBe("gpt-5.3");
});
});

Expand Down
12 changes: 8 additions & 4 deletions apps/web/src/composerDraftStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import { DeepMutable } from "effect/Types";
import {
createModelSelection,
draftModelPickMatchesThread,
normalizeCustomModelSlug,
normalizeModelSlug,
} from "@t3tools/shared/model";
import { AsyncResult, Atom, type AtomRegistry } from "effect/reactivity";
Expand Down Expand Up @@ -990,7 +991,11 @@ function normalizeModelSelection(
const driverKindHint =
normalizeProviderDriverKind(candidate?.provider ?? legacy?.provider) ??
ProviderDriverKind.make("codex");
const model = normalizeModelSlug(rawModel, driverKindHint);
// Instance-scoped picks are already resolved slugs; a custom slug can match a static alias.
const model =
candidate?.instanceId === undefined
? normalizeModelSlug(rawModel, driverKindHint)
: normalizeCustomModelSlug(rawModel);
if (!model) {
return null;
}
Expand Down Expand Up @@ -3051,7 +3056,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()(
}
const instanceKey = options?.instanceId ?? defaultInstanceIdForDriver(normalizedProvider);
const fallbackModel =
normalizeModelSlug(options?.model, normalizedProvider) ??
normalizeCustomModelSlug(options?.model) ??
DEFAULT_MODEL_BY_PROVIDER[normalizedProvider] ??
DEFAULT_MODEL;
const providerOpts =
Expand Down Expand Up @@ -3083,8 +3088,7 @@ const composerDraftStore = create<ComposerDraftStoreState>()(
nextStickyMap[instanceKey] ??
base.modelSelectionByProvider[instanceKey] ??
createModelSelection(instanceKey, fallbackModel);
const rememberedModel =
normalizeModelSlug(options?.model, normalizedProvider) ?? stickyBase.model;
const rememberedModel = normalizeCustomModelSlug(options?.model) ?? stickyBase.model;
if (providerOpts) {
nextStickyMap[instanceKey] = createModelSelection(
instanceKey,
Expand Down
Loading