File size: 2,429 Bytes
411fba2
1778c9e
73a8db9
1778c9e
64cfbce
b1426d3
 
f48efbb
3138e12
936176c
1778c9e
936176c
 
1778c9e
86574c0
936176c
a8ce6ad
2488073
c670717
9b4caaa
a8ce6ad
 
 
1778c9e
 
 
 
a8ce6ad
 
97c4991
 
 
 
 
411fba2
 
f459835
25c63d0
9b4caaa
25c63d0
 
 
97c4991
936176c
25c63d0
97c4991
25c63d0
97c4991
25c63d0
 
97c4991
25c63d0
64cfbce
 
 
 
 
25c63d0
 
 
2488073
2087f3e
2488073
 
1778c9e
 
 
97c4991
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
<script lang="ts">
	import type { ConversationClass } from "$lib/state/conversations.svelte";
	import { models } from "$lib/state/models.svelte.js";
	import { isCustomModel, isHFModel, type Model } from "$lib/types.js";
	import IconCaret from "~icons/carbon/chevron-down";
	import Avatar from "../avatar.svelte";
	import ModelSelectorModal from "./model-selector-modal.svelte";
	import ProviderSelect from "./provider-select.svelte";

	interface Props {
		conversation: ConversationClass;
	}

	const { conversation }: Props = $props();

	let showModelPickerModal = $state(false);

	// Model
	function changeModel(modelId: Model["id"]) {
		const model = models.all.find(m => m.id === modelId);
		if (!model) {
			return;
		}
		conversation.update({
			modelId: model.id,
			provider: undefined,
		});
	}

	const model = $derived(conversation.model);
	const isCustom = $derived(isCustomModel(model));
	const nameSpace = $derived(isCustom ? "Custom endpoint" : (model.id.split("/")[0] ?? ""));
	const modelName = $derived(isCustom ? model.id : (model.id.split("/")[1] ?? ""));
	const id = $props.id();
</script>

<div class="flex flex-col gap-2">
	<label for={id} class="flex items-baseline gap-2 text-sm font-medium text-gray-900 dark:text-white">
		Models<span class="text-xs font-normal text-gray-400">{models.all.length}</span>
	</label>
	<button
		{id}
		class="focus-outline 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"
		onclick={() => (showModelPickerModal = true)}
	>
		<div class="overflow-hidden text-start">
			<div class="flex items-center gap-1 text-sm text-gray-500 dark:text-gray-300">
				<Avatar model={conversation.model} orgName={nameSpace} size="sm" />
				{nameSpace}
			</div>
			<div class="truncate">{modelName}</div>
		</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>

{#if showModelPickerModal}
	<ModelSelectorModal {conversation} onModelSelect={changeModel} onClose={() => (showModelPickerModal = false)} />
{/if}

{#if isHFModel(conversation.model)}
	<!-- eslint-disable-next-line @typescript-eslint/no-explicit-any -->
	<ProviderSelect conversation={conversation as any} />
{/if}