File size: 5,388 Bytes
8000347
b924465
4b8b411
60216ec
b924465
60216ec
 
b924465
4b8b411
25c63d0
b924465
 
 
 
 
 
 
60216ec
 
 
 
c02e352
79d3242
6bcbb4b
8709c70
 
60216ec
c02e352
 
60216ec
 
b924465
c02e352
 
ce92b65
 
 
 
 
 
16c3549
 
 
 
 
 
b924465
 
 
 
 
7083ad1
16c3549
 
 
b924465
7083ad1
 
c02e352
b6d0c8a
25c63d0
 
ce92b65
 
 
877b369
c02e352
b924465
79d3242
b37c7b7
 
b924465
b37c7b7
e1cf22b
 
6fdab00
bdc9315
 
 
 
c02e352
 
 
 
 
 
 
 
 
 
 
8709c70
 
 
 
 
73b6f4f
8709c70
 
 
 
bdc9315
 
e1cf22b
b924465
7083ad1
b924465
 
f250f57
b924465
 
 
 
 
f250f57
7083ad1
ce92b65
7083ad1
 
b924465
7083ad1
b924465
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7083ad1
b924465
 
 
 
 
 
7083ad1
79d3242
e1cf22b
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 type { Conversation } from "$lib/types";

	import hljs from "highlight.js/lib/core";
	import http from "highlight.js/lib/languages/http";
	import javascript from "highlight.js/lib/languages/javascript";
	import python from "highlight.js/lib/languages/python";
	import { createEventDispatcher, onDestroy } from "svelte";

	import { token } from "$lib/stores/token";
	import type { InferenceProvider } from "@huggingface/inference";
	import IconCopyCode from "../Icons/IconCopyCode.svelte";
	import {
		getInferenceSnippet,
		type GetInferenceSnippetReturn,
		type InferenceSnippetLanguage,
	} from "./inferencePlaygroundUtils";

	hljs.registerLanguage("javascript", javascript);
	hljs.registerLanguage("python", python);
	hljs.registerLanguage("http", http);

	export let conversation: Conversation;

	const dispatch = createEventDispatcher<{ closeCode: void }>();

	const lanuages = ["javascript", "python", "http"];
	type Language = (typeof lanuages)[number];
	const labelsByLanguage: Record<Language, string> = {
		javascript: "JavaScript",
		python: "Python",
		http: "cURL",
	};

	let selectedLanguage: Language = "javascript";
	let timeout: ReturnType<typeof setTimeout>;
	let showToken = false;

	$: tokenStr = getTokenStr(showToken);

	type GetSnippetArgs = {
		tokenStr: string;
		conversation: Conversation;
		lang: InferenceSnippetLanguage;
	};
	function getSnippet({ tokenStr, conversation, lang }: GetSnippetArgs) {
		return getInferenceSnippet(conversation.model, conversation.provider as InferenceProvider, lang, tokenStr, {
			messages: conversation.messages,
		});
	}

	$: clientSnippetsByLang = {
		javascript: getSnippet({ lang: "js", tokenStr, conversation }),
		python: getSnippet({ lang: "python", tokenStr, conversation }),
		http: getSnippet({ lang: "curl", tokenStr, conversation }),
	} as Record<Language, GetInferenceSnippetReturn>;

	const selectedClientIdxByLang: Record<Language, number> = Object.fromEntries(lanuages.map(lang => [lang, 0]));

	function getTokenStr(showToken: boolean) {
		if ($token.value && showToken) {
			return $token.value;
		}
		return "YOUR_HF_TOKEN";
	}

	function highlight(code: string, language: Language) {
		return hljs.highlight(code, { language: language === "curl" ? "http" : language }).value;
	}

	onDestroy(() => {
		clearTimeout(timeout);
	});
</script>

<div class="px-2 pt-2">
	<div
		class="border-b border-gray-200 text-center text-sm font-medium text-gray-500 dark:border-gray-700 dark:text-gray-400"
	>
		<ul class="-mb-px flex flex-wrap">
			{#each Object.entries(labelsByLanguage) as [language, label]}
				<li>
					<button
						on:click={() => (selectedLanguage = language)}
						class="inline-block rounded-t-lg border-b-2 p-4 {language === selectedLanguage
							? 'border-black text-black dark:border-blue-500 dark:text-blue-500'
							: 'border-transparent hover:border-gray-300 hover:text-gray-600 dark:hover:text-gray-300'}"
						aria-current="page">{label}</button
					>
				</li>
			{/each}
			<li class="ml-auto self-center max-sm:hidden">
				<button
					on:click={() => {
						dispatch("closeCode");
					}}
					class="flex size-7 items-center justify-center rounded-lg px-3 py-2.5 text-xs font-medium text-gray-900 focus:ring-4 focus:ring-gray-100 focus:outline-hidden dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white dark:focus:ring-gray-700"
				>

				</button>
			</li>
		</ul>
	</div>

	{#if (clientSnippetsByLang[selectedLanguage]?.length ?? 0) > 1}
		<div class="flex gap-x-2 px-2 pt-6">
			{#each clientSnippetsByLang[selectedLanguage] ?? [] as { client }, idx}
				{@const isActive = idx === selectedClientIdxByLang[selectedLanguage]}
				<button
					class="rounded-lg border px-1.5 py-0.5 text-sm leading-tight
					{isActive
						? 'bg-black text-gray-100 dark:border-gray-500 dark:bg-gray-700 dark:text-white'
						: 'text-gray-500 hover:text-gray-600 dark:border-gray-600 dark:hover:text-gray-400'}"
					on:click={() => (selectedClientIdxByLang[selectedLanguage] = idx)}>{client}</button
				>
			{/each}
		</div>
	{/if}

	{#each clientSnippetsByLang[selectedLanguage] ?? [] as { language, content }, idx}
		{#if idx === selectedClientIdxByLang[selectedLanguage]}
			<div class="flex items-center justify-end px-2 pt-6 pb-4">
				<div class="flex items-center gap-x-4">
					<label class="flex items-center gap-x-1.5 text-sm select-none">
						<input type="checkbox" bind:checked={showToken} />
						<p class="leading-none">With token</p>
					</label>
					<button
						class="flex items-center gap-x-2 rounded-md border bg-white px-1.5 py-0.5 text-sm shadow-xs transition dark:border-gray-800 dark:bg-gray-800"
						on:click={e => {
							const el = e.currentTarget;
							el.classList.add("text-green-500");
							navigator.clipboard.writeText(content);
							if (timeout) {
								clearTimeout(timeout);
							}
							timeout = setTimeout(() => {
								el.classList.remove("text-green-500");
							}, 400);
						}}
					>
						<IconCopyCode classNames="text-xs" /> Copy code
					</button>
				</div>
			</div>
			<pre
				class="overflow-x-auto rounded-lg border border-gray-200/80 bg-white px-4 py-6 text-sm shadow-xs dark:border-gray-800 dark:bg-gray-800/50">{@html highlight(
					content,
					language ?? selectedLanguage
				)}</pre>
		{/if}
	{/each}
</div>