File size: 4,446 Bytes
e99e7c2
a1a6daf
f679146
a8a9533
e99e7c2
 
f311ca9
ff934bb
e99e7c2
f311ca9
d35c031
cdc7abc
d35c031
 
e99e7c2
 
 
a1a6daf
 
 
 
 
 
 
 
 
e99e7c2
a1a6daf
 
 
 
e99e7c2
a1a6daf
e99e7c2
 
 
f311ca9
 
a1a6daf
f311ca9
e99e7c2
f311ca9
4ef3bdf
f311ca9
 
 
 
 
 
4ef3bdf
 
 
 
 
 
 
 
 
 
 
e99e7c2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
cdc7abc
 
 
 
 
 
 
 
 
 
 
 
 
f311ca9
a1a6daf
f311ca9
 
df3243b
f311ca9
 
 
e99e7c2
 
 
d35c031
e99e7c2
a1a6daf
 
d35c031
a1a6daf
d35c031
 
e99e7c2
 
d35c031
 
e99e7c2
 
ff934bb
e99e7c2
 
 
 
 
a1a6daf
 
 
 
e99e7c2
 
 
 
 
 
db63053
e99e7c2
 
a1a6daf
 
 
ff934bb
 
a1a6daf
ff934bb
 
 
 
e99e7c2
 
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<script lang="ts">
	import { page } from "$app/state";
	import { base } from "$app/paths";
	import { env as envPublic } from "$env/dynamic/public";
	import type { BackendModel } from "$lib/server/models";
	import { useSettingsStore } from "$lib/stores/settings";
	import CopyToClipBoardBtn from "$lib/components/CopyToClipBoardBtn.svelte";
	import TokensCounter from "$lib/components/TokensCounter.svelte";
	import CarbonArrowUpRight from "~icons/carbon/arrow-up-right";
	import CarbonLink from "~icons/carbon/link";
	import CarbonChat from "~icons/carbon/chat";
	import CarbonCode from "~icons/carbon/code";

	import { goto } from "$app/navigation";

	const settings = useSettingsStore();

	$effect(() => {
		if ($settings.customPrompts[page.params.model] === undefined) {
			$settings.customPrompts = {
				...$settings.customPrompts,
				[page.params.model]:
					page.data.models.find((el: BackendModel) => el.id === page.params.model)?.preprompt || "",
			};
		}
	});

	let hasCustomPreprompt = $derived(
		$settings.customPrompts[page.params.model] !==
			page.data.models.find((el: BackendModel) => el.id === page.params.model)?.preprompt
	);

	let model = $derived(page.data.models.find((el: BackendModel) => el.id === page.params.model));
</script>

<div class="flex flex-col items-start">
	<div class="mb-5 flex flex-col gap-1.5">
		<h2 class="text-lg font-semibold md:text-xl">
			{page.params.model}
		</h2>

		{#if model.description}
			<p class="whitespace-pre-wrap text-gray-600">
				{model.description}
			</p>
		{/if}
	</div>

	<div class="flex flex-wrap items-center gap-2 md:gap-4">
		{#if model.modelUrl}
			<a
				href={model.modelUrl || "https://huggingface.co/" + model.name}
				target="_blank"
				rel="noreferrer"
				class="flex items-center truncate underline underline-offset-2"
			>
				<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
				Model page
			</a>
		{/if}

		{#if model.datasetName || model.datasetUrl}
			<a
				href={model.datasetUrl || "https://huggingface.co/datasets/" + model.datasetName}
				target="_blank"
				rel="noreferrer"
				class="flex items-center truncate underline underline-offset-2"
			>
				<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
				Dataset page
			</a>
		{/if}

		{#if model.websiteUrl}
			<a
				href={model.websiteUrl}
				target="_blank"
				class="flex items-center truncate underline underline-offset-2"
				rel="noreferrer"
			>
				<CarbonArrowUpRight class="mr-1.5 shrink-0 text-xs " />
				Model website
			</a>
		{/if}

		{#if model.hasInferenceAPI}
			<a
				href={"https://huggingface.co/playground?modelId=" + model.name}
				target="_blank"
				rel="noreferrer"
				class="flex items-center truncate underline underline-offset-2"
			>
				<CarbonCode class="mr-1.5 shrink-0 text-xs " />
				API Playground
			</a>
		{/if}

		<CopyToClipBoardBtn
			value="{envPublic.PUBLIC_ORIGIN || page.url.origin}{base}/models/{model.id}"
			classNames="!border-none !shadow-none !py-0 !px-1 !rounded-md"
		>
			<div class="flex items-center gap-1.5 hover:underline">
				<CarbonLink />Copy direct link to model
			</div>
		</CopyToClipBoardBtn>
	</div>

	<button
		class="my-2 flex w-fit items-center rounded-full bg-black px-3 py-1 text-base !text-white"
		name="Activate model"
		onclick={(e) => {
			e.stopPropagation();
			settings.instantSet({
				activeModel: page.params.model,
			});
			goto(`${base}/`);
		}}
	>
		<CarbonChat class="mr-1.5 text-sm" />
		New chat
	</button>

	<div class="relative flex w-full flex-col gap-2">
		<div class="flex w-full flex-row content-between">
			<h3 class="mb-1.5 text-lg font-semibold text-gray-800">System Prompt</h3>
			{#if hasCustomPreprompt}
				<button
					class="ml-auto underline decoration-gray-300 hover:decoration-gray-700"
					onclick={(e) => {
						e.stopPropagation();
						$settings.customPrompts[page.params.model] = model.preprompt;
					}}
				>
					Reset
				</button>
			{/if}
		</div>
		<textarea
			aria-label="Custom system prompt"
			rows="10"
			class="w-full resize-none rounded-md border-2 bg-gray-100 p-2"
			bind:value={$settings.customPrompts[page.params.model]}
		></textarea>
		{#if model.tokenizer && $settings.customPrompts[page.params.model]}
			<TokensCounter
				classNames="absolute bottom-2 right-2"
				prompt={$settings.customPrompts[page.params.model]}
				modelTokenizer={model.tokenizer}
				truncate={model?.parameters?.truncate}
			/>
		{/if}
	</div>
</div>