feat: persist last-used model in LocalStorage instead of preference

Drop the summaryModel preference (and the awkward textfield holding a
raw model ID nobody could discover without poking the SDK types). Each
AI view now controls its model dropdown, loads the shared
velum.ai.last-model on mount, and writes it back on submit — so picking
Claude 4.7 Opus in the summarize command becomes the prefilled default
in briefing, action-items, structured-data, and reply next time around.

Also drops 'model' from ReplyDefaults; the shared key supersedes it.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
muena
2026-05-20 07:33:27 +02:00
parent cc4742cf38
commit 9bc621307c
11 changed files with 88 additions and 52 deletions

View File

@@ -12,11 +12,13 @@ import { useEffect, useMemo, useState } from "react";
import {
type Creativity,
CREATIVITY_OPTIONS,
DEFAULT_MODEL,
getLastUsedModel,
MODEL_OPTIONS,
setLastUsedModel,
STRICT_PLACEHOLDER_RULE,
} from "./ai";
import { PseudonymizationConfirm } from "./ai-views";
import { getPreferences } from "./preferences";
import { getSelectedTextSafely } from "./selection";
import {
createSession,
@@ -80,23 +82,25 @@ type FormValues = {
};
export default function Command() {
const preferences = getPreferences();
const [text, setText] = useState("");
const [sessions, setSessions] = useState<VelumSession[]>([]);
const [activeSessionId, setActiveSessionId] = useState<string>();
const [entityTypes, setEntityTypes] = useState<EntityType[]>([]);
const [selectedEntityTypes, setSelectedEntityTypes] = useState<string[]>([]);
const [model, setModel] = useState<string>(DEFAULT_MODEL);
const [isLoading, setIsLoading] = useState(true);
const { push } = useNavigation();
useEffect(() => {
async function load() {
const [loadedSessions, activeId] = await Promise.all([
const [loadedSessions, activeId, lastModel] = await Promise.all([
listSessions(),
getActiveSessionId(),
getLastUsedModel(),
]);
setSessions(loadedSessions);
setActiveSessionId(activeId);
setModel(lastModel);
const selection = await getSelectedTextSafely();
if (selection && selection.trim()) {
@@ -155,6 +159,8 @@ export default function Command() {
return;
}
void setLastUsedModel(values.model);
const toast = await showToast({
style: Toast.Style.Animated,
title: "Pseudonymisiere…",
@@ -277,7 +283,8 @@ export default function Command() {
<Form.Dropdown
id="model"
title="KI-Modell"
defaultValue={preferences.summaryModel}
value={model}
onChange={setModel}
>
{MODEL_OPTIONS.map((option) => (
<Form.Dropdown.Item