enzostvs HF Staff commited on
Commit
f60772d
·
1 Parent(s): 24bab0f

api instructions

Browse files
src/lib/components/chat/User.svelte CHANGED
@@ -14,13 +14,12 @@
14
  import { onMount } from 'svelte';
15
 
16
  import ErrorMessage from '$lib/components/error/Error.svelte';
17
- import type { ChatModel, ChatMessage } from '$lib/helpers/types';
18
  import { Button } from '$lib/components/ui/button';
19
  import ComboBoxModels from '$lib/components/model/ComboBoxModels.svelte';
20
  import Spinner from '$lib/components/loading/Spinner.svelte';
21
  import Message from './Message.svelte';
22
- import SettingsModel from '$lib/components/model/SettingsModel.svelte';
23
- import { MAX_MODELS_PER_NODE, MAX_SUGGESTIONS } from '$lib';
24
  import { triggerAiCall } from '$lib/chat';
25
  import { SUGGESTIONS_PROMPT } from '$lib/consts';
26
  import { authState } from '$lib/state/auth.svelte';
 
14
  import { onMount } from 'svelte';
15
 
16
  import ErrorMessage from '$lib/components/error/Error.svelte';
17
+ import type { ChatMessage } from '$lib/helpers/types';
18
  import { Button } from '$lib/components/ui/button';
19
  import ComboBoxModels from '$lib/components/model/ComboBoxModels.svelte';
20
  import Spinner from '$lib/components/loading/Spinner.svelte';
21
  import Message from './Message.svelte';
22
+ import { MAX_SUGGESTIONS } from '$lib';
 
23
  import { triggerAiCall } from '$lib/chat';
24
  import { SUGGESTIONS_PROMPT } from '$lib/consts';
25
  import { authState } from '$lib/state/auth.svelte';
src/lib/components/chat/markdown/Code.svelte CHANGED
@@ -1,13 +1,25 @@
1
  <script lang="ts">
2
  import Button from '$lib/components/ui/button/button.svelte';
3
- import { Copy } from '@lucide/svelte';
4
  import { HighlightAuto } from 'svelte-highlight';
5
  import 'svelte-highlight/styles/github.css';
6
 
7
- let { lang, text }: { lang?: string; text: string } = $props();
 
 
 
 
 
 
 
 
 
 
 
 
8
  </script>
9
 
10
- <div class="relative my-3 overflow-hidden rounded-lg border border-border/60 bg-muted/50">
11
  {#if lang}
12
  <div class="flex items-center justify-between border-b border-border/60 bg-muted px-3 py-1.5">
13
  <span class="font-mono text-[11px] text-muted-foreground">{lang}</span>
@@ -17,10 +29,15 @@
17
  <HighlightAuto code={text} class="font-mono text-[13px] leading-relaxed" />
18
  <Button
19
  variant="outline"
20
- size="icon-xs"
21
  class="absolute top-2 right-2 opacity-0 group-hover:opacity-100"
 
 
22
  >
23
- <Copy />
 
 
 
 
24
  </Button>
25
  </div>
26
  </div>
 
1
  <script lang="ts">
2
  import Button from '$lib/components/ui/button/button.svelte';
3
+ import { Check, Copy } from '@lucide/svelte';
4
  import { HighlightAuto } from 'svelte-highlight';
5
  import 'svelte-highlight/styles/github.css';
6
 
7
+ let {
8
+ lang,
9
+ text,
10
+ className = 'my-3 relative rounded-lg border border-border/60 bg-muted/50'
11
+ }: { lang?: string; text: string; className?: string } = $props();
12
+
13
+ let copiedCode = $state(false);
14
+
15
+ async function copy(text: string) {
16
+ await navigator.clipboard.writeText(text);
17
+ copiedCode = true;
18
+ setTimeout(() => (copiedCode = false), 2000);
19
+ }
20
  </script>
21
 
22
+ <div class="overflow-hidden {className}">
23
  {#if lang}
24
  <div class="flex items-center justify-between border-b border-border/60 bg-muted px-3 py-1.5">
25
  <span class="font-mono text-[11px] text-muted-foreground">{lang}</span>
 
29
  <HighlightAuto code={text} class="font-mono text-[13px] leading-relaxed" />
30
  <Button
31
  variant="outline"
 
32
  class="absolute top-2 right-2 opacity-0 group-hover:opacity-100"
33
+ size="icon-xs"
34
+ onclick={() => copy(text)}
35
  >
36
+ {#if copiedCode}
37
+ <Check class="size-3.5 text-green-500" />
38
+ {:else}
39
+ <Copy class="size-3.5" />
40
+ {/if}
41
  </Button>
42
  </div>
43
  </div>
src/lib/components/flow/actions/InstructionsModal.svelte ADDED
@@ -0,0 +1,258 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import { CodeXml, ExternalLink } from '@lucide/svelte';
3
+
4
+ import { Button } from '$lib/components/ui/button';
5
+ import * as Dialog from '$lib/components/ui/sheet/index.js';
6
+ import Code from '$lib/components/chat/markdown/Code.svelte';
7
+ import { useSvelteFlow } from '@xyflow/svelte';
8
+
9
+ type Instruction = {
10
+ library: string;
11
+ doc_link: string;
12
+ install: string;
13
+ code: string;
14
+ };
15
+
16
+ type Language = {
17
+ language: string;
18
+ instructions: Instruction[];
19
+ };
20
+
21
+ const { getNodes } = useSvelteFlow();
22
+
23
+ const instructions: Language[] = [
24
+ {
25
+ language: 'JavaScript',
26
+ instructions: [
27
+ {
28
+ library: 'openai',
29
+ doc_link: 'https://platform.openai.com/docs/libraries',
30
+ install: 'npm install openai',
31
+ code: `import OpenAI from "openai";
32
+
33
+ const client = new OpenAI({
34
+ baseURL: "https://router.huggingface.co/v1",
35
+ apiKey: process.env.HF_TOKEN,
36
+ });
37
+
38
+ const stream = client.chat.completions.stream({
39
+ model: "meta-llama/Llama-3.1-8B-Instruct",
40
+ messages: [{ role: "user", content: "What is the capital of France?" }],
41
+ stream: true,
42
+ });
43
+
44
+ for await (const chunk of stream) {
45
+ process.stdout.write(chunk.choices[0]?.delta?.content || "");
46
+ }`
47
+ },
48
+ {
49
+ library: 'huggingface.js',
50
+ doc_link: 'https://huggingface.co/docs/huggingface.js/inference/README',
51
+ install: 'npm install @huggingface/inference',
52
+ code: `import { InferenceClient } from "@huggingface/inference";
53
+
54
+ const client = new InferenceClient(process.env.HF_TOKEN);
55
+
56
+ let output = "";
57
+ for await (const chunk of client.chatCompletionStream({
58
+ model: "meta-llama/Llama-3.1-8B-Instruct",
59
+ messages: [{ role: "user", content: "What is the capital of France?" }],
60
+ max_tokens: 512,
61
+ })) {
62
+ output += chunk.choices[0].delta.content;
63
+ }
64
+ console.log(output);`
65
+ }
66
+ ]
67
+ },
68
+ {
69
+ language: 'Python',
70
+ instructions: [
71
+ {
72
+ library: 'openai',
73
+ doc_link: 'https://platform.openai.com/docs/libraries',
74
+ install: 'pip install --upgrade openai',
75
+ code: `import os
76
+ from openai import OpenAI
77
+
78
+ client = OpenAI(
79
+ base_url="https://router.huggingface.co/v1",
80
+ api_key=os.environ.get("HF_TOKEN"),
81
+ )
82
+
83
+ stream = client.chat.completions.create(
84
+ model="meta-llama/Llama-3.1-8B-Instruct",
85
+ messages=[{"role": "user", "content": "What is the capital of France?"}],
86
+ stream=True,
87
+ )
88
+ for chunk in stream:
89
+ print(chunk.choices[0].delta.content, end="", flush=True)`
90
+ },
91
+ {
92
+ library: 'huggingface_hub',
93
+ doc_link: 'https://huggingface.co/docs/huggingface_hub/guides/inference',
94
+ install: 'pip install --upgrade huggingface_hub',
95
+ code: `import os
96
+ from huggingface_hub import InferenceClient
97
+
98
+ client = InferenceClient(
99
+ provider="auto",
100
+ api_key=os.environ.get("HF_TOKEN"),
101
+ )
102
+
103
+ for message in client.chat_completion(
104
+ model="meta-llama/Llama-3.1-8B-Instruct",
105
+ messages=[{"role": "user", "content": "What is the capital of France?"}],
106
+ max_tokens=500,
107
+ stream=True,
108
+ ):
109
+ print(message.choices[0].delta.content, end="")`
110
+ },
111
+ {
112
+ library: 'requests',
113
+ doc_link: 'https://requests.readthedocs.io/en/latest/',
114
+ install: 'pip install requests',
115
+ code: `import os
116
+ import json
117
+ import requests
118
+
119
+ API_URL = "https://router.huggingface.co/v1/chat/completions"
120
+ headers = {"Authorization": f"Bearer {os.environ['HF_TOKEN']}"}
121
+
122
+ def query(payload):
123
+ response = requests.post(API_URL, headers=headers, json=payload, stream=True)
124
+ for line in response.iter_lines():
125
+ if not line.startswith(b"data:"):
126
+ continue
127
+ if line.strip() == b"data: [DONE]":
128
+ return
129
+ yield json.loads(line.decode("utf-8").lstrip("data:"))
130
+
131
+ chunks = query({
132
+ "messages": [{"role": "user", "content": "What is the capital of France?"}],
133
+ "temperature": 0.5,
134
+ "top_p": 0.7,
135
+ "model": "meta-llama/Llama-3.1-8B-Instruct",
136
+ "stream": True,
137
+ })
138
+ for chunk in chunks:
139
+ print(chunk["choices"][0]["delta"]["content"], end="")`
140
+ }
141
+ ]
142
+ },
143
+ {
144
+ language: 'cURL',
145
+ instructions: [
146
+ {
147
+ library: 'curl',
148
+ doc_link: 'https://huggingface.co/docs/api-inference/getting-started',
149
+ install: '',
150
+ code: `curl https://router.huggingface.co/v1/chat/completions \\
151
+ -H "Authorization: Bearer $HF_TOKEN" \\
152
+ -H "Content-Type: application/json" \\
153
+ -d '{
154
+ "model": "meta-llama/Llama-3.1-8B-Instruct",
155
+ "messages": [
156
+ { "role": "user", "content": "What is the capital of France?" }
157
+ ],
158
+ "stream": true
159
+ }'`
160
+ }
161
+ ]
162
+ }
163
+ ];
164
+
165
+ let open = $state(false);
166
+ let selectedLanguage = $state<string>(instructions[0].language);
167
+ let selectedLibrary = $state<string>(instructions[0].instructions[0].library);
168
+
169
+ let languageData = $derived(instructions.find((i) => i.language === selectedLanguage));
170
+ let libraryData = $derived(languageData?.instructions.find((i) => i.library === selectedLibrary));
171
+ let showLibraryTabs = $derived((languageData?.instructions.length ?? 0) > 1);
172
+
173
+ // let nodeInformation = $derived(getNodes()[getNodes().length - 1]?.data ?? null);
174
+ // let modelInformation = $derived(
175
+ // modelsState.models.find(
176
+ // (m) =>
177
+ // m.id === (nodeInformation?.selectedModel as string) ||
178
+ // m.id === (nodeInformation?.selectedModels as string[])[0]
179
+ // )
180
+ // );
181
+
182
+ function selectLanguage(lang: string) {
183
+ selectedLanguage = lang;
184
+ const langData = instructions.find((i) => i.language === lang);
185
+ if (langData) selectedLibrary = langData.instructions[0].library;
186
+ }
187
+ </script>
188
+
189
+ <Dialog.Root bind:open>
190
+ <Dialog.Trigger class="">
191
+ <Button variant="outline">
192
+ <CodeXml />
193
+ How to use the API
194
+ </Button>
195
+ </Dialog.Trigger>
196
+
197
+ <Dialog.Content class="max-w-xl! gap-0! p-0!">
198
+ <Dialog.Header class="mb-0 gap-1! rounded-none border-b p-5">
199
+ <Dialog.Title>Use the API</Dialog.Title>
200
+ <Dialog.Description>Integrate this model into your application.</Dialog.Description>
201
+ </Dialog.Header>
202
+
203
+ <div class="space-y-4 p-5">
204
+ <div class="flex items-center gap-1.5">
205
+ {#each instructions as lang}
206
+ <Button
207
+ variant={selectedLanguage === lang.language ? 'default' : 'outline'}
208
+ size="default"
209
+ onclick={() => selectLanguage(lang.language)}
210
+ >
211
+ {lang.language}
212
+ </Button>
213
+ {/each}
214
+ </div>
215
+
216
+ {#if showLibraryTabs && languageData}
217
+ <div class="flex items-center gap-1.5">
218
+ {#each languageData.instructions as instr}
219
+ <Button
220
+ variant={selectedLibrary === instr.library ? 'outline-blue' : 'outline'}
221
+ size="xs"
222
+ class="rounded-full!"
223
+ onclick={() => (selectedLibrary = instr.library)}
224
+ >
225
+ {instr.library}
226
+ </Button>
227
+ {/each}
228
+ </div>
229
+ {/if}
230
+
231
+ {#if libraryData}
232
+ {#if libraryData.install}
233
+ <div class="overflow-hidden rounded-lg border border-border">
234
+ <div class="flex items-center justify-between border-b border-border px-3.5 py-2.5">
235
+ <p class="text-xs font-semibold text-primary">Install</p>
236
+ </div>
237
+ <Code text={libraryData.install} className="" />
238
+ </div>
239
+ {/if}
240
+
241
+ <div class="overflow-hidden rounded-lg border border-border">
242
+ <div class="flex items-center justify-between border-b border-border px-3.5 py-2.5">
243
+ <p class="text-xs font-semibold text-primary">Streaming API</p>
244
+ <div class="flex items-center gap-1.5">
245
+ <a href={libraryData.doc_link} target="_blank" rel="noopener noreferrer">
246
+ <Button variant="outline" size="2xs">
247
+ <ExternalLink class="size-3.5" />
248
+ View documentation
249
+ </Button>
250
+ </a>
251
+ </div>
252
+ </div>
253
+ <Code text={libraryData.code} className="" />
254
+ </div>
255
+ {/if}
256
+ </div>
257
+ </Dialog.Content>
258
+ </Dialog.Root>
src/lib/components/flow/actions/PanelRightActions.svelte CHANGED
@@ -1,6 +1,6 @@
1
  <script lang="ts">
2
  import { Contrast, CreditCard, Monitor, Moon, RefreshCcw, Sun } from '@lucide/svelte';
3
- import { Panel, useNodes, useSvelteFlow } from '@xyflow/svelte';
4
  import { setMode } from 'mode-watcher';
5
 
6
  import { Button } from '$lib/components/ui/button';
@@ -9,6 +9,7 @@
9
  import { billingModalState } from '$lib/state/billing-modal.svelte';
10
  import defaultAvatar from '$lib/assets/default-avatar.svg';
11
  import BillingManagementModal from '$lib/components/billing/BillingManagementModal.svelte';
 
12
 
13
  let { canReset }: { canReset: boolean } = $props();
14
 
@@ -31,6 +32,7 @@
31
  Start new chat
32
  </Button>
33
  {/if}
 
34
  <DropdownMenu.Root>
35
  <DropdownMenu.Trigger>
36
  {#snippet child({ props })}
 
1
  <script lang="ts">
2
  import { Contrast, CreditCard, Monitor, Moon, RefreshCcw, Sun } from '@lucide/svelte';
3
+ import { Panel, useSvelteFlow } from '@xyflow/svelte';
4
  import { setMode } from 'mode-watcher';
5
 
6
  import { Button } from '$lib/components/ui/button';
 
9
  import { billingModalState } from '$lib/state/billing-modal.svelte';
10
  import defaultAvatar from '$lib/assets/default-avatar.svg';
11
  import BillingManagementModal from '$lib/components/billing/BillingManagementModal.svelte';
12
+ import InstructionsModal from './InstructionsModal.svelte';
13
 
14
  let { canReset }: { canReset: boolean } = $props();
15
 
 
32
  Start new chat
33
  </Button>
34
  {/if}
35
+ <InstructionsModal />
36
  <DropdownMenu.Root>
37
  <DropdownMenu.Trigger>
38
  {#snippet child({ props })}
src/lib/components/ui/button/button.svelte CHANGED
@@ -4,7 +4,7 @@
4
  import { type VariantProps, tv } from 'tailwind-variants';
5
 
6
  export const buttonVariants = tv({
7
- base: "focus-visible:border-ring cursor-pointer focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
8
  variants: {
9
  variant: {
10
  default:
@@ -16,7 +16,8 @@
16
  outline:
17
  'bg-background hover:bg-accent hover:text-accent-foreground dark:bg-gray-900/70 dark:border-border dark:hover:bg-gray-800/70 border shadow-xs text-gray-600 dark:text-gray-400',
18
  secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-xs',
19
- ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
 
20
  link: 'text-primary underline-offset-4 hover:underline',
21
  'outline-blue':
22
  'bg-blue-500/10 text-blue-500 border border-blue-500/20 hover:bg-blue-500/20 shadow-xs',
 
4
  import { type VariantProps, tv } from 'tailwind-variants';
5
 
6
  export const buttonVariants = tv({
7
+ base: "focus-visible:border-ring cursor-pointer border border-border focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4",
8
  variants: {
9
  variant: {
10
  default:
 
16
  outline:
17
  'bg-background hover:bg-accent hover:text-accent-foreground dark:bg-gray-900/70 dark:border-border dark:hover:bg-gray-800/70 border shadow-xs text-gray-600 dark:text-gray-400',
18
  secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80 shadow-xs',
19
+ ghost:
20
+ 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50 border-transparent!',
21
  link: 'text-primary underline-offset-4 hover:underline',
22
  'outline-blue':
23
  'bg-blue-500/10 text-blue-500 border border-blue-500/20 hover:bg-blue-500/20 shadow-xs',
src/routes/+page.svelte CHANGED
@@ -14,7 +14,6 @@
14
  import { modelsState } from '$lib/state/models.svelte';
15
  import User from '$lib/components/chat/User.svelte';
16
  import Assistant from '$lib/components/chat/Assistant.svelte';
17
- import type { ChatModel } from '$lib/helpers/types';
18
  import FitViewOnResize from '$lib/components/flow/FitViewOnResize.svelte';
19
  import PanelRightActions from '$lib/components/flow/actions/PanelRightActions.svelte';
20
  import { MAX_DEFAULT_MODELS } from '$lib';
@@ -22,7 +21,6 @@
22
  import { viewState } from '$lib/state/view.svelte';
23
  import ContextMenuComponent from '$lib/components/flow/actions/ContextMenu.svelte';
24
  import { getNodesAssociatedWith } from '$lib/helpers/getNodesAssociatedWith';
25
- import PanelLeftMenu from '$lib/components/flow/actions/PanelLeftMenu.svelte';
26
  import { breakpointsState } from '$lib/state/breakpoints.svelte';
27
 
28
  const nodeTypes = {
 
14
  import { modelsState } from '$lib/state/models.svelte';
15
  import User from '$lib/components/chat/User.svelte';
16
  import Assistant from '$lib/components/chat/Assistant.svelte';
 
17
  import FitViewOnResize from '$lib/components/flow/FitViewOnResize.svelte';
18
  import PanelRightActions from '$lib/components/flow/actions/PanelRightActions.svelte';
19
  import { MAX_DEFAULT_MODELS } from '$lib';
 
21
  import { viewState } from '$lib/state/view.svelte';
22
  import ContextMenuComponent from '$lib/components/flow/actions/ContextMenu.svelte';
23
  import { getNodesAssociatedWith } from '$lib/helpers/getNodesAssociatedWith';
 
24
  import { breakpointsState } from '$lib/state/breakpoints.svelte';
25
 
26
  const nodeTypes = {