mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-10-01 10:27:30 -05:00
ui : mark external provider rows with the provider icon
Assisted-by: pi:llama.cpp/DeepSeek-V4.1-Flash
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
<script lang="ts">
|
||||
import BackendPresetIcon from './BackendPresetIcon.svelte';
|
||||
import type { Backend } from '$lib/types';
|
||||
import { backendFaviconUrl, findBackendPreset } from '$lib/utils';
|
||||
import { SvelteSet } from 'svelte/reactivity';
|
||||
|
||||
/** Favicons that failed to load, so a row remount does not ask again. */
|
||||
const failedFavicons = new SvelteSet<string>();
|
||||
|
||||
interface Props {
|
||||
backend?: Backend;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
let { backend, class: className = 'h-4 w-4' }: Props = $props();
|
||||
|
||||
let preset = $derived(backend ? findBackendPreset(backend.baseUrl) : undefined);
|
||||
let faviconUrl = $derived(preset || !backend ? null : backendFaviconUrl(backend.baseUrl));
|
||||
</script>
|
||||
|
||||
{#if preset}
|
||||
<BackendPresetIcon class={className} {preset} />
|
||||
{:else if faviconUrl && !failedFavicons.has(faviconUrl)}
|
||||
<img
|
||||
alt=""
|
||||
class={['shrink-0 rounded-sm object-contain', className]}
|
||||
decoding="async"
|
||||
loading="lazy"
|
||||
onerror={() => failedFavicons.add(faviconUrl)}
|
||||
src={faviconUrl}
|
||||
/>
|
||||
{/if}
|
||||
@@ -1,5 +1,6 @@
|
||||
export { default as BackendCard } from './BackendCard.svelte';
|
||||
export { default as BackendForm } from './BackendForm.svelte';
|
||||
export { default as BackendIcon } from './BackendIcon.svelte';
|
||||
export { default as BackendPresetCard } from './BackendPresetCard.svelte';
|
||||
export { default as BackendPresetIcon } from './BackendPresetIcon.svelte';
|
||||
export { default as DialogBackendForm } from './DialogBackendForm.svelte';
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
RotateCw
|
||||
} from '@lucide/svelte';
|
||||
import { ActionIcon, ModelId } from '$lib/components/app';
|
||||
import { BackendIcon } from '$lib/components/app/backends';
|
||||
import { HF_BASE_MODEL_TAG_REGEX, ICON_CLASS_DEFAULT } from '$lib/constants';
|
||||
import { ModelCapability, ServerModelStatus } from '$lib/enums';
|
||||
import { HuggingFaceService, ModelsService } from '$lib/services';
|
||||
@@ -222,7 +223,13 @@
|
||||
</div>
|
||||
|
||||
{#if !canLoad}
|
||||
<!-- remote rows have no load state, the column stays out of the way -->
|
||||
<!-- external providers carry no load state: the row shows the provider
|
||||
mark instead, which is what identifies it in a flat list -->
|
||||
{#if rowBackend}
|
||||
<div class="flex w-5 items-center justify-center">
|
||||
<BackendIcon backend={rowBackend} class="h-3.5 w-3.5" />
|
||||
</div>
|
||||
{/if}
|
||||
{:else if isLoading}
|
||||
<div class="flex w-5 items-center justify-center">
|
||||
<Loader2 class="{ICON_CLASS_DEFAULT} animate-spin text-muted-foreground" />
|
||||
|
||||
@@ -34,6 +34,23 @@ export function backendModelsUrl(backend: Backend): string {
|
||||
return joinBackendUrl(backend.baseUrl, backend.modelsPath ?? DEFAULT_BACKEND_MODELS_PATH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Favicon of a backend's root domain, for endpoints with no bundled mark. API
|
||||
* hosts rarely serve one, so the subdomain is dropped: `api.z.ai` -> `z.ai`.
|
||||
* Returns null when the URL carries no usable host.
|
||||
*/
|
||||
export function backendFaviconUrl(baseUrl: string): string | null {
|
||||
try {
|
||||
const { hostname, protocol } = new URL(baseUrl);
|
||||
const labels = hostname.split('.');
|
||||
const root = labels.length > 2 ? labels.slice(-2).join('.') : hostname;
|
||||
|
||||
return `${protocol}//${root}/favicon.ico`;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preset a backend was created from, matched on origin and path so a saved
|
||||
* backend keeps its branding. Returns undefined for edited or custom URLs.
|
||||
|
||||
@@ -26,6 +26,7 @@ export { ApiError, apiDelete, apiFetch, apiFetchWithParams, apiPost } from './ap
|
||||
export { validateApiKey } from './api-key-validation';
|
||||
export {
|
||||
backendChatUrl,
|
||||
backendFaviconUrl,
|
||||
backendModelsUrl,
|
||||
createLocalBackend,
|
||||
findBackendPreset,
|
||||
|
||||
Reference in New Issue
Block a user