Spaces:
Runtime error
Runtime error
File size: 3,300 Bytes
9ab40fd 0a3474b 936176c 97c4991 9ab40fd 7357f85 c6f83f5 64cfbce 812d95a 9ab40fd 936176c 97c4991 936176c 9ab40fd b924465 9ab40fd 936176c 9ab40fd c6f83f5 936176c 9ab40fd c6f83f5 ba9894c 9ab40fd f5e7fbe 01e2d92 9ab40fd 64cfbce 9ab40fd c6f83f5 01e2d92 c6f83f5 9ab40fd b7dc03e 9ab40fd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
<script lang="ts">
import { run } from "svelte/legacy";
import type { ConversationWithHFModel } from "$lib/types.js";
import { randomPick } from "$lib/utils/array.js";
import { cn } from "$lib/utils/cn.js";
import { Select } from "melt/builders";
import IconCaret from "~icons/carbon/chevron-down";
import IconProvider from "../icon-provider.svelte";
interface Props {
conversation: ConversationWithHFModel;
class?: string | undefined;
}
let { conversation = $bindable(), class: classes = undefined }: Props = $props();
function reset(providers: typeof conversation.model.inferenceProviderMapping) {
const validProvider = providers.find(p => p.provider === conversation.provider);
if (validProvider) return;
conversation.provider = randomPick(providers)?.provider;
}
let providers = $derived(conversation.model.inferenceProviderMapping);
run(() => {
reset(providers);
});
const select = new Select<string, false>({
value: () => conversation.provider,
onValueChange(v) {
conversation.provider = v;
},
});
const nameMap: Record<string, string> = {
"sambanova": "SambaNova",
"fal": "fal",
"cerebras": "Cerebras",
"replicate": "Replicate",
"black-forest-labs": "Black Forest Labs",
"fireworks-ai": "Fireworks",
"together": "Together AI",
"nebius": "Nebius AI Studio",
"hyperbolic": "Hyperbolic",
"novita": "Novita",
"cohere": "Nohere",
"hf-inference": "HF Inference API",
};
const UPPERCASE_WORDS = ["hf", "ai"];
function formatName(provider: string) {
if (provider in nameMap) return nameMap[provider];
const words = provider
.toLowerCase()
.split("-")
.map(word => {
if (UPPERCASE_WORDS.includes(word)) {
return word.toUpperCase();
} else {
return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
}
});
return words.join(" ");
}
</script>
<div class="flex flex-col gap-2">
<!--
<label class="flex items-baseline gap-2 text-sm font-medium text-gray-900 dark:text-white">
Providers<span class="text-xs font-normal text-gray-400"></span>
</label>
-->
<button
{...select.trigger}
class={cn(
"relative flex items-center justify-between gap-6 overflow-hidden rounded-lg border bg-gray-100/80 px-3 py-1.5 leading-tight whitespace-nowrap shadow-sm",
"hover:brightness-95 dark:border-gray-700 dark:bg-gray-800 dark:hover:brightness-110",
classes
)}
>
<div class="flex items-center gap-1 text-sm">
<IconProvider provider={conversation.provider} />
{formatName(conversation.provider ?? "") ?? "loading"}
</div>
<div
class="absolute right-2 grid size-4 flex-none place-items-center rounded-sm bg-gray-100 text-xs dark:bg-gray-600"
>
<IconCaret />
</div>
</button>
<div {...select.content} class="rounded-lg border bg-gray-100 dark:border-gray-700 dark:bg-gray-800">
{#each conversation.model.inferenceProviderMapping as { provider, providerId } (provider + providerId)}
<button {...select.getOption(provider)} class="group block w-full p-1 text-sm dark:text-white">
<div
class="flex items-center gap-2 rounded-md px-2 py-1.5 group-data-[highlighted]:bg-gray-200 dark:group-data-[highlighted]:bg-gray-700"
>
<IconProvider {provider} />
{formatName(provider)}
</div>
</button>
{/each}
</div>
</div>
|