feat(webui): show the actual fallback model (#5017)

This commit is contained in:
chengyongru
2026-07-23 15:57:13 +08:00
committed by GitHub
parent 4188ffc88d
commit 96eb965aae
15 changed files with 352 additions and 8 deletions
@@ -170,6 +170,7 @@ interface ThreadComposerProps {
modelProvider?: string | null;
modelProviderLabel?: string | null;
modelNeedsSetup?: boolean;
fallbackModelName?: string | null;
onModelBadgeClick?: () => void;
variant?: "thread" | "hero";
slashCommands?: SlashCommand[];
@@ -815,6 +816,7 @@ export function ThreadComposer({
modelProvider = null,
modelProviderLabel = null,
modelNeedsSetup = false,
fallbackModelName = null,
onModelBadgeClick,
variant = "thread",
slashCommands = [],
@@ -2073,6 +2075,7 @@ export function ThreadComposer({
provider={modelProvider}
providerLabel={modelProviderLabel}
needsSetup={modelNeedsSetup}
fallbackModelName={fallbackModelName}
isHero={isHero}
onClick={modelNeedsSetup ? onModelBadgeClick : undefined}
/>
@@ -2361,6 +2364,7 @@ function ComposerModelBadge({
provider,
providerLabel,
needsSetup,
fallbackModelName,
isHero,
onClick,
}: {
@@ -2368,6 +2372,7 @@ function ComposerModelBadge({
provider?: string | null;
providerLabel?: string | null;
needsSetup?: boolean;
fallbackModelName?: string | null;
isHero: boolean;
onClick?: () => void;
}) {
@@ -2381,11 +2386,12 @@ function ComposerModelBadge({
return (
<Container
title={title}
data-fallback={fallbackModelName ? "true" : undefined}
title={fallbackModelName || title}
type={interactive ? "button" : undefined}
onClick={onClick}
className={cn(
"inline-flex min-w-0 items-center rounded-full border border-border/55 bg-card font-medium text-foreground/82",
"composer-model-badge inline-flex min-w-0 items-center rounded-full border border-border/55 bg-card font-medium text-foreground/82",
"shadow-[0_2px_8px_rgba(15,23,42,0.045)]",
interactive && "cursor-pointer hover:bg-accent/55 hover:text-foreground",
needsSetup && "border-amber-500/35 bg-amber-50/70 text-amber-900 dark:bg-amber-500/10 dark:text-amber-200",
@@ -333,6 +333,7 @@ export function ThreadShell({
forkBoundaryMessageCount,
} = useSessionHistory(historyKey);
const { client, ingressLimits, modelName, token } = useClient();
const [fallbackModelName, setFallbackModelName] = useState<string | null>(null);
const [booting, setBooting] = useState(false);
const [slashCommands, setSlashCommands] = useState<SlashCommand[]>([]);
const cliApps = useInstalledSettingItems({
@@ -379,6 +380,7 @@ export function ThreadShell({
return messageCacheRef.current.get(chatId) ?? historical;
}, [chatId, historical]);
const handleTurnEnd = useCallback(() => {
setFallbackModelName(null);
onTurnEnd?.();
}, [onTurnEnd]);
const {
@@ -519,6 +521,18 @@ export function ThreadShell({
});
}, [client, refreshModelSettings]);
useEffect(() => {
if (!chatId) {
setFallbackModelName(null);
return;
}
setFallbackModelName(null);
return client.onChat(chatId, (event) => {
if (event.event !== "turn_model_updated") return;
setFallbackModelName(event.model_name);
});
}, [chatId, client]);
useEffect(() => {
if (!chatId || loading) return;
const cached = messageCacheRef.current.get(chatId);
@@ -680,6 +694,7 @@ export function ThreadShell({
const handleThreadSend = useCallback(
(content: string, images?: SendAttachment[], options?: SendOptions) => {
setFallbackModelName(null);
setScrollToLatestUserPromptSignal((value) => value + 1);
send(content, images, withWorkspaceScope(options));
},
@@ -808,6 +823,7 @@ export function ThreadShell({
modelProvider={modelBadge.provider}
modelProviderLabel={modelBadge.providerLabel}
modelNeedsSetup={modelBadge.needsSetup}
fallbackModelName={fallbackModelName}
onModelBadgeClick={modelBadge.needsSetup ? onOpenModelSettings : undefined}
variant={showHeroComposer ? "hero" : "thread"}
slashCommands={slashCommands}
@@ -845,6 +861,7 @@ export function ThreadShell({
modelProvider={modelBadge.provider}
modelProviderLabel={modelBadge.providerLabel}
modelNeedsSetup={modelBadge.needsSetup}
fallbackModelName={fallbackModelName}
onModelBadgeClick={modelBadge.needsSetup ? onOpenModelSettings : undefined}
variant="hero"
slashCommands={slashCommands}