fix: sync assistant runtime preferences

This commit is contained in:
ajnart committed 2026-08-13 19:56:27 +02:00
1 parent 7899d8677c
commit cb1a73a6ac
6 files changed
+94 -10

No files matched your search

@@ -256,6 +256,7 @@ export const AssistantConfiguration = () => {
await Promise.all([
utils.assistant.getAdminConfiguration.invalidate(),
utils.assistant.getAvailability.invalidate(),
utils.assistant.getRuntimeOptions.invalidate(),
]);
showSuccessNotification({
title: t("notification.saved.title"),
@@ -988,6 +988,10 @@
flex: 1 1 auto;
}
.modelButton :global(.mantine-Button-label) {
font-size: var(--mantine-font-size-xs);
}
.reasoningButton {
min-width: 7.5rem;
max-width: 10.5rem;
@@ -0,0 +1,54 @@
import { describe, expect, test } from "vitest";
import { resolveAssistantPreferenceModelId } from "./assistant-preferences";
const models = [
{ id: "provider/default", name: "Default", inputModalities: ["text"] },
{ id: "provider/alternate", name: "Alternate", inputModalities: ["text"] },
];
describe("resolveAssistantPreferenceModelId", () => {
test("uses the server default when preferences first load", () => {
expect(
resolveAssistantPreferenceModelId({
currentModelId: null,
previousDefaultModelId: undefined,
defaultModelId: "provider/default",
models,
}),
).toBe("provider/default");
});
test("adopts a changed server default even when the old model remains available", () => {
expect(
resolveAssistantPreferenceModelId({
currentModelId: "provider/default",
previousDefaultModelId: "provider/default",
defaultModelId: "provider/alternate",
models,
}),
).toBe("provider/alternate");
});
test("preserves an available conversation selection while the default is unchanged", () => {
expect(
resolveAssistantPreferenceModelId({
currentModelId: "provider/alternate",
previousDefaultModelId: "provider/default",
defaultModelId: "provider/default",
models,
}),
).toBe("provider/alternate");
});
test("falls back to the default when the selected model is no longer available", () => {
expect(
resolveAssistantPreferenceModelId({
currentModelId: "provider/removed",
previousDefaultModelId: "provider/default",
defaultModelId: "provider/default",
models,
}),
).toBe("provider/default");
});
});
@@ -5,3 +5,19 @@ export type AssistantRuntimeModelOption = {
name: string;
inputModalities: string[];
};
export const resolveAssistantPreferenceModelId = ({
currentModelId,
previousDefaultModelId,
defaultModelId,
models,
}: {
currentModelId: string | null;
previousDefaultModelId: string | null | undefined;
defaultModelId: string | null;
models: readonly AssistantRuntimeModelOption[];
}) => {
if (previousDefaultModelId !== defaultModelId) return defaultModelId;
if (currentModelId && models.some((model) => model.id === currentModelId)) return currentModelId;
return defaultModelId;
};
@@ -30,6 +30,7 @@ import { AssistantAskUserTool, AssistantConfigureAppTool } from "./assistant-hum
import { AssistantPanel } from "./assistant-panel";
import { getPendingAssistantAction } from "./assistant-pending-action";
import type { AssistantReasoningMode, AssistantRuntimeModelOption } from "./assistant-preferences";
import { resolveAssistantPreferenceModelId } from "./assistant-preferences";
import { AssistantRuntimeProviderWithTools } from "./assistant-runtime-provider";
import { sendAssistantPrompt as sendPromptThroughComposer } from "./assistant-send";
import { createAssistantPromptInteraction } from "./assistant-spotlight";
@@ -163,6 +164,7 @@ const AssistantPreferencesProvider = ({ children }: PropsWithChildren) => {
});
const [modelId, setModelIdState] = useState<string | null>(null);
const [reasoning, setReasoningState] = useState<AssistantReasoningMode>("auto");
const previousDefaultModelIdRef = useRef<string | null | undefined>(undefined);
const preferencesRef = useRef<{ modelId: string | null; reasoning: AssistantReasoningMode }>({
modelId: null,
reasoning: "auto",
@@ -190,10 +192,17 @@ const AssistantPreferencesProvider = ({ children }: PropsWithChildren) => {
useEffect(() => {
if (!data) return;
const currentModelId = preferencesRef.current.modelId;
if (currentModelId && data.models.some((model) => model.id === currentModelId)) return;
setModelId(data.defaultModelId);
}, [data, setModelId]);
const nextModelId = resolveAssistantPreferenceModelId({
currentModelId: preferencesRef.current.modelId,
previousDefaultModelId: previousDefaultModelIdRef.current,
defaultModelId: data.defaultModelId,
models: data.models,
});
previousDefaultModelIdRef.current = data.defaultModelId;
if (nextModelId === preferencesRef.current.modelId) return;
preferencesRef.current.modelId = nextModelId;
setModelIdState(nextModelId);
}, [data]);
const value = useMemo(
() => ({
+6 -6
View File
@@ -2012,12 +2012,12 @@
"noModels": "No models available",
"thinking": "Thinking mode",
"reasoning": {
"auto": "Thinking: Auto",
"none": "Thinking: Off",
"minimal": "Thinking: Minimal",
"low": "Thinking: Low",
"medium": "Thinking: Medium",
"high": "Thinking: High"
"auto": "Auto",
"none": "Off",
"minimal": "Minimal",
"low": "Low",
"medium": "Medium",
"high": "High"
}
},
"stop": "Stop response",