mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-05-27 22:25:29 +08:00
fix: clarify model refresh and onboarding providers
OpenCode is now a supported chat provider, but first-run onboarding still only offered Claude, Cursor, Codex, and Gemini. That made OpenCode harder to discover and forced users to finish setup before finding the provider in settings or chat. Adding it to onboarding keeps first-run setup aligned with the providers the application already supports elsewhere. The model refresh control was also doing too much visual work. In the new chat model picker, the previous Hard Refresh label looked like the dialog heading, which made the primary task unclear. Users open that dialog to choose a model; refreshing catalogs is only a secondary maintenance action for stale cached provider model lists. Rename and reposition the refresh affordance so the model picker reads as a model picker first. The copy now explains why catalogs are cached, when a refresh is useful, and that the refresh checks every provider. The /models modal gets the same clarification so both model-selection surfaces describe the cache behavior consistently.
This commit is contained in:
@@ -346,7 +346,7 @@ function ModelsContent({
|
||||
return (
|
||||
<div className="flex h-full min-h-0 flex-col gap-2.5">
|
||||
<div className="rounded-2xl border border-border/70 bg-muted/20 p-2.5">
|
||||
<div className="grid gap-2.5 lg:grid-cols-[minmax(0,1.75fr)_minmax(13rem,0.75fr)_auto] lg:items-start">
|
||||
<div className="grid gap-2.5 lg:grid-cols-[minmax(0,1.55fr)_minmax(12rem,0.7fr)_minmax(15rem,0.9fr)] lg:items-start">
|
||||
<div className="min-w-0">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<Badge variant="secondary" className="rounded-lg border border-primary/20 bg-primary/10 px-2.5 py-1 text-[10px] font-semibold uppercase tracking-[0.18em] text-primary">
|
||||
@@ -387,17 +387,31 @@ function ModelsContent({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onHardRefreshProviderModels}
|
||||
disabled={providerModelsRefreshing}
|
||||
className="h-8 shrink-0 rounded-xl px-3 lg:self-start"
|
||||
>
|
||||
<RefreshCw className={providerModelsRefreshing ? 'animate-spin' : ''} />
|
||||
{providerModelsRefreshing ? 'Refreshing...' : 'Hard Refresh'}
|
||||
</Button>
|
||||
<div className="rounded-xl border border-border/60 bg-background/55 p-2.5">
|
||||
<div className="flex flex-wrap items-center gap-1.5">
|
||||
<p className="text-[10px] font-bold uppercase tracking-[0.18em] text-foreground/80">
|
||||
Catalog Refresh
|
||||
</p>
|
||||
<Badge variant="secondary" className="rounded-md px-1.5 py-0 text-[9px] uppercase tracking-[0.14em]">
|
||||
All providers
|
||||
</Badge>
|
||||
</div>
|
||||
<p className="mt-1.5 text-[11px] leading-4 text-muted-foreground">
|
||||
Model lists are cached for 3 days. Refresh after CLI, auth, or config changes,
|
||||
or when a new model is missing.
|
||||
</p>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onHardRefreshProviderModels}
|
||||
disabled={providerModelsRefreshing}
|
||||
className="mt-2 h-8 w-full rounded-xl px-3"
|
||||
>
|
||||
<RefreshCw className={providerModelsRefreshing ? 'animate-spin' : ''} />
|
||||
{providerModelsRefreshing ? 'Refreshing catalogs...' : 'Refresh from providers'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-2 border-t border-border/50 pt-1.5 text-[11px] text-muted-foreground">
|
||||
|
||||
@@ -265,29 +265,29 @@ export default function ProviderSelectionEmptyState({
|
||||
<DialogContent className="max-w-md overflow-hidden p-0">
|
||||
<DialogTitle>Model Selector</DialogTitle>
|
||||
<div className="border-b border-border/60 bg-muted/20 px-4 py-3">
|
||||
<div className="flex items-start justify-between gap-3">
|
||||
<div className="min-w-0">
|
||||
<p className="text-sm font-semibold text-foreground">
|
||||
Hard refresh model catalogs
|
||||
</p>
|
||||
<p className="mt-1 text-xs leading-5 text-muted-foreground">
|
||||
Bypasses the 3-day backend cache and re-fetches models for every provider.
|
||||
</p>
|
||||
<p className="mt-1 text-[11px] text-muted-foreground">
|
||||
Last updated for {getProviderDisplayName(provider)}: {formatUpdatedAt(currentProviderCache?.updatedAt)}
|
||||
</p>
|
||||
<div className="space-y-2">
|
||||
<div className="flex flex-wrap items-start justify-between gap-3">
|
||||
<div className="min-w-0 flex-1">
|
||||
<p className="text-sm font-semibold text-foreground">Choose a model</p>
|
||||
<p className="mt-0.5 text-xs leading-5 text-muted-foreground">
|
||||
Catalogs are cached for 3 days. Refresh after CLI/auth changes or if a model is missing.
|
||||
</p>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onHardRefreshProviderModels}
|
||||
disabled={providerModelsRefreshing}
|
||||
className="shrink-0 rounded-xl"
|
||||
>
|
||||
<RefreshCw className={providerModelsRefreshing ? "animate-spin" : ""} />
|
||||
{providerModelsRefreshing ? "Refreshing..." : "Refresh"}
|
||||
</Button>
|
||||
</div>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onHardRefreshProviderModels}
|
||||
disabled={providerModelsRefreshing}
|
||||
className="shrink-0 rounded-xl"
|
||||
>
|
||||
<RefreshCw className={providerModelsRefreshing ? "animate-spin" : ""} />
|
||||
{providerModelsRefreshing ? "Refreshing..." : "Hard Refresh"}
|
||||
</Button>
|
||||
<p className="text-[11px] text-muted-foreground">
|
||||
Refresh checks every provider and replaces the cached catalogs. Last updated for {getProviderDisplayName(provider)}: {formatUpdatedAt(currentProviderCache?.updatedAt)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Command>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { LLMProvider } from '../../../../types/app';
|
||||
import type { ProviderAuthStatusMap } from '../../../provider-auth/types';
|
||||
|
||||
import AgentConnectionCard from './AgentConnectionCard';
|
||||
|
||||
type AgentConnectionsStepProps = {
|
||||
@@ -36,6 +37,13 @@ const providerCards = [
|
||||
iconContainerClassName: 'bg-teal-100 dark:bg-teal-900/30',
|
||||
loginButtonClassName: 'bg-teal-600 hover:bg-teal-700',
|
||||
},
|
||||
{
|
||||
provider: 'opencode' as const,
|
||||
title: 'OpenCode',
|
||||
connectedClassName: 'bg-zinc-100 dark:bg-zinc-800/50 border-zinc-300 dark:border-zinc-600',
|
||||
iconContainerClassName: 'bg-zinc-100 dark:bg-zinc-800',
|
||||
loginButtonClassName: 'bg-zinc-800 hover:bg-zinc-900 dark:bg-zinc-700 dark:hover:bg-zinc-600',
|
||||
},
|
||||
];
|
||||
|
||||
export default function AgentConnectionsStep({
|
||||
|
||||
Reference in New Issue
Block a user