chore: unify connection copy (#5654)
This commit is contained in:
parent
155f6de22b
commit
469dbd6278
3 changed files with 49 additions and 42 deletions
|
|
@ -255,7 +255,7 @@ function ModelSelectorContent({
|
|||
<Tabs defaultValue={chatOnlyTabsDefault} className="w-full">
|
||||
<TabsList className="mb-2 w-full">
|
||||
<TabsTrigger value="hub">Hub models</TabsTrigger>
|
||||
<TabsTrigger value="external">External</TabsTrigger>
|
||||
<TabsTrigger value="external">Connected</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="hub" className="m-0">
|
||||
<HubModelPicker models={models} value={value} onSelect={onSelect} onFoldersChange={onFoldersChange} />
|
||||
|
|
@ -276,7 +276,7 @@ function ModelSelectorContent({
|
|||
<TabsList className="mb-2 w-full">
|
||||
<TabsTrigger value="hub">Hub models</TabsTrigger>
|
||||
<TabsTrigger value="lora">Fine-tuned</TabsTrigger>
|
||||
{hasExternal ? <TabsTrigger value="external">External</TabsTrigger> : null}
|
||||
{hasExternal ? <TabsTrigger value="external">Connected</TabsTrigger> : null}
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="hub" className="m-0">
|
||||
|
|
@ -530,15 +530,22 @@ function ExternalModelPicker({
|
|||
<Input
|
||||
value={query}
|
||||
onChange={(event) => setQuery(event.target.value)}
|
||||
placeholder="Search external models"
|
||||
placeholder="Search models"
|
||||
className="h-9 pl-8"
|
||||
/>
|
||||
</div>
|
||||
<div className="max-h-64 overflow-y-auto">
|
||||
<div className="space-y-2 p-1">
|
||||
{grouped.length === 0 ? (
|
||||
<div className="px-2.5 py-2 text-xs text-muted-foreground">
|
||||
No external models configured.
|
||||
<div className="px-2.5 py-2 text-xs leading-relaxed text-muted-foreground">
|
||||
{externalModels.length === 0 ? (
|
||||
<>
|
||||
No models from your connections. Set up in Settings →
|
||||
Connections.
|
||||
</>
|
||||
) : (
|
||||
"No models match your search."
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
grouped.map((group) => (
|
||||
|
|
|
|||
|
|
@ -775,7 +775,7 @@ export function createOpenAIStreamAdapter(): ChatModelAdapter {
|
|||
) {
|
||||
toast.error("Connections are disabled.", {
|
||||
description:
|
||||
"Turn on Enable connections in Settings > Connections to use hosted models.",
|
||||
"Turn on Enable connections in Settings → Connections to use hosted models.",
|
||||
});
|
||||
throw new Error("Connections disabled.");
|
||||
}
|
||||
|
|
@ -789,20 +789,20 @@ export function createOpenAIStreamAdapter(): ChatModelAdapter {
|
|||
: "";
|
||||
|
||||
if (isExternalRequest && !externalProvider) {
|
||||
toast.error("External provider not found.", {
|
||||
description: "Open Connections and re-add this provider.",
|
||||
toast.error("Connection not found.", {
|
||||
description: "Open Settings → Connections and add it again.",
|
||||
});
|
||||
throw new Error("External provider not found.");
|
||||
throw new Error("Connection not found.");
|
||||
}
|
||||
// Local providers (llama.cpp / vLLM / Ollama) allow an empty key — only block hosted providers.
|
||||
const externalProviderIsCustom = externalProvider
|
||||
? isCustomProviderType(externalProvider.providerType)
|
||||
: false;
|
||||
if (isExternalRequest && !externalApiKey && !externalProviderIsCustom) {
|
||||
toast.error("Missing API key for selected external provider.", {
|
||||
description: "Open Connections and set the API key again.",
|
||||
toast.error("Missing API key for selected connection.", {
|
||||
description: "Open Settings → Connections and set the API key again.",
|
||||
});
|
||||
throw new Error("Missing external provider API key.");
|
||||
throw new Error("Missing connection API key.");
|
||||
}
|
||||
|
||||
const outboundMessages = messages
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ const PROVIDER_FORM_EASE: [number, number, number, number] = [
|
|||
];
|
||||
const PROVIDER_FORM_DURATION = 0.2;
|
||||
const CUSTOM_PROVIDER_MISSING_KEY_MESSAGE =
|
||||
"No API key found, please make sure API key is added and valid for this provider.";
|
||||
"No API key found. Add a valid API key for this connection.";
|
||||
const ANTHROPIC_DATED_SNAPSHOT_SUFFIX = /-\d{8}$/;
|
||||
const OPENAI_DEPRECATED_MODELS = new Set(["gpt-5.3"]);
|
||||
const HIDDEN_PROVIDER_TYPES = new Set(["qwen"]);
|
||||
|
|
@ -166,7 +166,7 @@ function emptyCatalogHint(providerType: string): {
|
|||
} {
|
||||
return (
|
||||
EMPTY_CATALOG_HINTS[providerType] ?? {
|
||||
title: "No models returned by this provider.",
|
||||
title: "No models returned by this connection.",
|
||||
description: "Enter model IDs manually below, or check the server.",
|
||||
}
|
||||
);
|
||||
|
|
@ -290,7 +290,7 @@ export function ChatProvidersSettings({
|
|||
isManualModelList && isCustomProvider
|
||||
? "This connection uses manual model IDs"
|
||||
: isCuratedModelList
|
||||
? "Full catalog is not fetched for this provider"
|
||||
? "Full catalog is not fetched for this connection"
|
||||
: missingModelCatalogBaseUrl
|
||||
? "Enter a Base URL before loading models"
|
||||
: missingModelCatalogApiKey
|
||||
|
|
@ -414,7 +414,7 @@ export function ChatProvidersSettings({
|
|||
} catch (error) {
|
||||
const message =
|
||||
error instanceof Error ? error.message : "Unknown error";
|
||||
toast.error(`Failed to load providers: ${message}`);
|
||||
toast.error(`Failed to load connections: ${message}`);
|
||||
} finally {
|
||||
if (isMounted) {
|
||||
setRegistryLoading(false);
|
||||
|
|
@ -514,7 +514,7 @@ export function ChatProvidersSettings({
|
|||
|
||||
async function loadModels() {
|
||||
if (!providerType) {
|
||||
toast.error("Choose a provider first.");
|
||||
toast.error("Choose a connection first.");
|
||||
return;
|
||||
}
|
||||
if (isCustomProvider && !supportsRemoteModelCatalog(providerType)) {
|
||||
|
|
@ -523,7 +523,7 @@ export function ChatProvidersSettings({
|
|||
}
|
||||
if (isCuratedModelList) {
|
||||
toast.info(
|
||||
"This provider has a very large model catalog. Use the suggestions and add model IDs manually — full list is not fetched.",
|
||||
"This connection has a very large model catalog. Use the suggestions and add model IDs manually — full list is not fetched.",
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -591,7 +591,7 @@ export function ChatProvidersSettings({
|
|||
|
||||
async function addProvider() {
|
||||
if (!providerType) {
|
||||
toast.error("Choose a provider first.");
|
||||
toast.error("Choose a connection first.");
|
||||
return;
|
||||
}
|
||||
const backendProviderType = toExternalBackendProviderType(providerType);
|
||||
|
|
@ -688,10 +688,10 @@ export function ChatProvidersSettings({
|
|||
]);
|
||||
resetForm();
|
||||
setPage("list");
|
||||
toast.success("Provider added.");
|
||||
toast.success("Connection added.");
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unknown error";
|
||||
toast.error(`Failed to add provider: ${message}`);
|
||||
toast.error(`Failed to add connection: ${message}`);
|
||||
} finally {
|
||||
setMutatingProvider(false);
|
||||
}
|
||||
|
|
@ -703,7 +703,7 @@ export function ChatProvidersSettings({
|
|||
(provider) => provider.id === editingProviderId,
|
||||
);
|
||||
if (!existing) {
|
||||
toast.error("Provider not found.");
|
||||
toast.error("Connection not found.");
|
||||
return;
|
||||
}
|
||||
const isEditingCustomProvider =
|
||||
|
|
@ -799,12 +799,12 @@ export function ChatProvidersSettings({
|
|||
: provider,
|
||||
),
|
||||
);
|
||||
toast.success("Provider updated.");
|
||||
toast.success("Connection updated.");
|
||||
resetForm();
|
||||
setPage("list");
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unknown error";
|
||||
toast.error(`Failed to update provider: ${message}`);
|
||||
toast.error(`Failed to update connection: ${message}`);
|
||||
} finally {
|
||||
setMutatingProvider(false);
|
||||
}
|
||||
|
|
@ -890,7 +890,7 @@ export function ChatProvidersSettings({
|
|||
);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : "Unknown error";
|
||||
toast.error(`Failed to delete provider: ${message}`);
|
||||
toast.error(`Failed to delete connection: ${message}`);
|
||||
} finally {
|
||||
setMutatingProvider(false);
|
||||
}
|
||||
|
|
@ -906,7 +906,7 @@ export function ChatProvidersSettings({
|
|||
return;
|
||||
}
|
||||
await editProvider(provider);
|
||||
toast.info(`No API key found for ${provider.name}. Add one and save.`);
|
||||
toast.info(`No API key for ${provider.name}. Add one in Connections and save.`);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
|
|
@ -952,8 +952,8 @@ export function ChatProvidersSettings({
|
|||
size="icon-sm"
|
||||
className="size-8 rounded-[8px]"
|
||||
onClick={closeForm}
|
||||
aria-label="Back to providers"
|
||||
title="Back to providers"
|
||||
aria-label="Back to connections"
|
||||
title="Back to connections"
|
||||
>
|
||||
<HugeiconsIcon icon={ArrowLeft02Icon} className="size-4" />
|
||||
</Button>
|
||||
|
|
@ -977,10 +977,10 @@ export function ChatProvidersSettings({
|
|||
htmlFor="provider-preset"
|
||||
className="text-sm font-medium"
|
||||
>
|
||||
Provider
|
||||
Connection
|
||||
</Label>
|
||||
<p className="text-xs leading-snug text-muted-foreground">
|
||||
Supported registry or local OpenAI-compatible connection.
|
||||
OpenAI, Anthropic, or a compatible local endpoint.
|
||||
</p>
|
||||
</div>
|
||||
<Select
|
||||
|
|
@ -1002,7 +1002,7 @@ export function ChatProvidersSettings({
|
|||
className="h-9 w-full text-sm"
|
||||
disabled={editingProviderId != null}
|
||||
>
|
||||
<SelectValue placeholder="Choose a provider" />
|
||||
<SelectValue placeholder="Choose a connection" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
|
|
@ -1094,7 +1094,7 @@ export function ChatProvidersSettings({
|
|||
htmlFor="provider-custom-name"
|
||||
className="text-sm font-medium"
|
||||
>
|
||||
Provider name
|
||||
Connection name
|
||||
</Label>
|
||||
<Input
|
||||
id="provider-custom-name"
|
||||
|
|
@ -1446,7 +1446,7 @@ export function ChatProvidersSettings({
|
|||
: void addProvider()
|
||||
}
|
||||
>
|
||||
{editingProviderId ? "Save provider" : "Add provider"}
|
||||
{editingProviderId ? "Save connection" : "Add connection"}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
|
|
@ -1470,7 +1470,7 @@ export function ChatProvidersSettings({
|
|||
<div className="flex min-w-0 flex-col gap-1">
|
||||
<h1 className="font-heading text-lg font-semibold">Connections</h1>
|
||||
<p className="text-xs leading-relaxed text-muted-foreground">
|
||||
Manage model provider connections for chat through the Studio proxy.
|
||||
Manage model connections for chat through the Studio proxy.
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
|
|
@ -1495,7 +1495,7 @@ export function ChatProvidersSettings({
|
|||
id="chat-connections-description"
|
||||
className="max-w-md text-[11px] leading-snug text-muted-foreground/65 sm:text-right"
|
||||
>
|
||||
When off, all provider connections are disabled.
|
||||
When off, all connections are disabled.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
|
@ -1508,20 +1508,20 @@ export function ChatProvidersSettings({
|
|||
>
|
||||
<span className="flex min-w-0 items-center gap-2 rounded-full border border-border bg-background/50 px-3 py-1.5 transition-colors group-hover/add:border-emerald-500/25 group-hover/add:text-emerald-700 dark:group-hover/add:text-emerald-300">
|
||||
<HugeiconsIcon icon={PlusSignIcon} className="size-4 shrink-0" />
|
||||
<span>Add Provider</span>
|
||||
<span>Add connection</span>
|
||||
</span>
|
||||
<span className="shrink-0 text-xs tabular-nums text-muted-foreground/90">
|
||||
{providers.length} providers · {totalModels} models
|
||||
{providers.length} connections · {totalModels} models
|
||||
</span>
|
||||
</button>
|
||||
{providers.length === 0 ? (
|
||||
<div className="px-3 py-4">
|
||||
<div className="flex min-w-0 flex-col gap-0.5">
|
||||
<span className="text-sm font-medium text-foreground">
|
||||
No providers yet
|
||||
No connections yet
|
||||
</span>
|
||||
<span className="text-xs leading-snug text-muted-foreground">
|
||||
Add an external provider to use hosted models from chat.
|
||||
Add a connection to use hosted models from chat.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1583,7 +1583,7 @@ export function ChatProvidersSettings({
|
|||
className="size-7 rounded-[8px] hover:text-foreground"
|
||||
disabled={mutatingProvider}
|
||||
onClick={() => editProvider(provider)}
|
||||
title="Edit provider"
|
||||
title="Edit connection"
|
||||
aria-label={`Edit ${provider.name}`}
|
||||
>
|
||||
<HugeiconsIcon icon={Edit03Icon} className="size-4" />
|
||||
|
|
@ -1607,7 +1607,7 @@ export function ChatProvidersSettings({
|
|||
className="size-7 rounded-[8px] hover:text-destructive"
|
||||
disabled={mutatingProvider}
|
||||
onClick={() => void deleteProvider(provider.id)}
|
||||
title="Delete provider"
|
||||
title="Delete connection"
|
||||
aria-label={`Delete ${provider.name}`}
|
||||
>
|
||||
<HugeiconsIcon icon={Delete02Icon} className="size-4" />
|
||||
|
|
@ -1644,7 +1644,7 @@ export function ChatProvidersDialog({
|
|||
<DialogHeader className="sr-only">
|
||||
<DialogTitle>Connections</DialogTitle>
|
||||
<DialogDescription>
|
||||
Manage external model connections for chat.
|
||||
Manage model connections for chat.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<ChatProvidersSettings
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue