Spaces:
Runtime error
Runtime error
File size: 3,482 Bytes
9ab40fd 936176c 7357f85 9ab40fd 7357f85 9ab40fd 64cfbce 812d95a 9ab40fd 936176c 9ab40fd b924465 9ab40fd 936176c 9ab40fd 936176c 9ab40fd ba9894c 9ab40fd f5e7fbe 01e2d92 9ab40fd 64cfbce 9ab40fd 693ced9 01e2d92 b7dc03e 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 111 112 113 114 115 116 117 |
<script lang="ts">
import { run } from 'svelte/legacy';
import type { Conversation } from "$lib/types.js";
import { randomPick } from "$lib/utils/array.js";
import { cn } from "$lib/utils/cn.js";
import { createSelect, createSync } from "@melt-ui/svelte";
import IconCaret from "~icons/carbon/chevron-down";
import IconProvider from "../icon-provider.svelte";
interface Props {
conversation: Conversation;
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 {
elements: { trigger, menu, option },
states: { selected },
} = createSelect<string, false>();
const sync = createSync({ selected });
run(() => {
sync.selected(
conversation.provider ? { value: conversation.provider } : undefined,
p => (conversation.provider = p?.value)
);
});
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
{...$trigger}
use: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 {...$menu} use:menu 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 {...$option({ value: provider })} use:option 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>
|