enzostvs HF staff commited on
Commit
13c9aca
·
1 Parent(s): b99fcde

add translation shot

Browse files
src/lib/components/Prompt.svelte CHANGED
@@ -1,6 +1,7 @@
1
  <script lang="ts">
2
  export let value: string;
3
  export let placeholder: string = "Ask me anything...";
 
4
  export let onChange: (v: string) => void
5
  </script>
6
 
@@ -9,7 +10,7 @@
9
  for="prompt"
10
  class="font-sans text-slate-400 font-regular text-sm"
11
  >
12
- Prompt:
13
  </label>
14
  <textarea
15
  id="prompt"
 
1
  <script lang="ts">
2
  export let value: string;
3
  export let placeholder: string = "Ask me anything...";
4
+ export let label: string | undefined = "Prompt";
5
  export let onChange: (v: string) => void
6
  </script>
7
 
 
10
  for="prompt"
11
  class="font-sans text-slate-400 font-regular text-sm"
12
  >
13
+ {label ?? 'Prompt'}:
14
  </label>
15
  <textarea
16
  id="prompt"
src/lib/components/SelectModel.svelte CHANGED
@@ -39,7 +39,10 @@
39
  height={22}
40
  class="rounded-full"
41
  />
42
- <p>{selectedModel.id}</p>
 
 
 
43
  </div>
44
  {:else}
45
  <p class="opacity-70">Select a model</p>
@@ -52,7 +55,7 @@
52
  class:opacity-0={!open}
53
  >
54
  <div class="bg-slate-900 border border-slate-700/80 text-white p-2 font-code rounded-lg">
55
- {#each items as { id, logo}}
56
  <button
57
  class={`w-full flex items-center justify-start gap-3 p-2 cursor-pointer hover:bg-slate-800/60 rounded-lg ${selectedModel?.id === id && 'bg-slate-800/60'}`}
58
  on:click={() => handleSelect(id)}
@@ -64,7 +67,7 @@
64
  height={22}
65
  class="rounded-full"
66
  />
67
- <p>{id}</p>
68
  </button>
69
  {/each}
70
  </div>
 
39
  height={22}
40
  class="rounded-full"
41
  />
42
+ <p>{selectedModel?.label ?? selectedModel?.id}</p>
43
+ {#if selectedModel?.label}
44
+ <p class="text-slate-400 text-xs">({selectedModel?.id})</p>
45
+ {/if}
46
  </div>
47
  {:else}
48
  <p class="opacity-70">Select a model</p>
 
55
  class:opacity-0={!open}
56
  >
57
  <div class="bg-slate-900 border border-slate-700/80 text-white p-2 font-code rounded-lg">
58
+ {#each items as { id, logo, label }}
59
  <button
60
  class={`w-full flex items-center justify-start gap-3 p-2 cursor-pointer hover:bg-slate-800/60 rounded-lg ${selectedModel?.id === id && 'bg-slate-800/60'}`}
61
  on:click={() => handleSelect(id)}
 
67
  height={22}
68
  class="rounded-full"
69
  />
70
+ <p>{label ?? id}</p>
71
  </button>
72
  {/each}
73
  </div>
src/lib/components/text-generation/Preview.svelte CHANGED
@@ -6,8 +6,7 @@
6
  </script>
7
 
8
  <div class="text-white p-6 font-code text-xs !leading-loose">
9
- {body.inputs ?? "No input provided"}
10
- {#if res?.[0]?.generated_text}
11
- <span>{res[0]?.generated_text?.replace(body?.inputs, "")}</span>
12
  {/if}
13
  </div>
 
6
  </script>
7
 
8
  <div class="text-white p-6 font-code text-xs !leading-loose">
9
+ {#if res?.[0]?.translation_text}
10
+ {res[0]?.translation_text}
 
11
  {/if}
12
  </div>
src/lib/components/translation/Form.svelte ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import Prompt from "$lib/components/Prompt.svelte";
3
+ import SelectModel from "$lib/components/SelectModel.svelte";
4
+ import { TRANSLATION_MODELS } from "$lib/utils/models";
5
+
6
+ export let form: Record<string, any>;
7
+ export let onForm: (form: Record<string, any>) => void;
8
+ </script>
9
+
10
+ <SelectModel value={form.model} items={TRANSLATION_MODELS} onChange={(model) => onForm({ ...form, model })} />
11
+ <Prompt
12
+ placeholder="Enter your text here..."
13
+ value={form.inputs}
14
+ onChange={(inputs) => onForm({ ...form, inputs })}
15
+ />
src/lib/components/translation/Response.svelte ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import Icon from '@iconify/svelte';
3
+ import Highlight from "svelte-highlight";
4
+ import json from "svelte-highlight/languages/json";
5
+ import "svelte-highlight/styles/night-owl.css"
6
+
7
+ import Loading from "$lib/components/Loading.svelte"
8
+ import CodePreview from '$lib/components/CodePreview.svelte';
9
+ import Preview from '$lib/components/text-generation/Preview.svelte';
10
+
11
+ export let loading: boolean;
12
+ export let res: any;
13
+ export let form: Record<string, any>;
14
+ export let body: Record<string, any>;
15
+ export let endpoint: string;
16
+
17
+ let tab = 0
18
+
19
+ $: code = JSON.stringify(res ?? {}, null, 2)
20
+
21
+ let TABS = [
22
+ {
23
+ label: "Formatted preview",
24
+ icon: "material-symbols:preview",
25
+ },
26
+ {
27
+ label: "Code example",
28
+ icon: "carbon:code",
29
+ },
30
+ ];
31
+ </script>
32
+
33
+ <div class="lg:h-screen flex flex-col relative">
34
+ <div class="w-full jsonResponse relative">
35
+ <div class="bg-slate-950 w-full uppercase px-5 py-4 text-zinc-400 text-sm font-semibold border-b border-slate-900 flex items-center justify-start gap-2">
36
+ <Icon icon="carbon:json" class="w-5 h-5" />
37
+ Response
38
+ </div>
39
+ <Highlight language={json} {code}>
40
+ </Highlight>
41
+ {#if loading}
42
+ <Loading>
43
+ <p class="text-slate-400 text-lg mt-4">Processing...</p>
44
+ </Loading>
45
+ {/if}
46
+ </div>
47
+ <div class="bg-slate-950 overflow-auto flex-1">
48
+ <div class="w-full uppercase text-zinc-400 text-sm font-semibold border-t border-slate-900 flex items-start sticky top-0 bg-slate-950">
49
+ {#each TABS as { label, icon }, idx }
50
+ <button
51
+ class={`flex items-center justify-start gap-2 px-5 border-r py-4 border-slate-900 bg-slate-900/40 cursor-pointer hover:bg-slate-900/60 transition-all duration-200 ${tab === idx ? '!bg-slate-950 hover:bg-slate-900/40' : 'border-b'}`}
52
+ on:click={() => tab = idx}
53
+ >
54
+ <Icon icon={icon} class="w-5 h-5" />
55
+ {label}
56
+ </button>
57
+ {/each}
58
+ <div class="flex flex-1 w-full pointer-events-none text-slate-950 border-b border-slate-900 h-[53px] bg-slate-900/40"></div>
59
+ </div>
60
+ {#if tab === 0}
61
+ <Preview body={body} res={res} />
62
+ {:else if tab === 1}
63
+ <CodePreview body={form} endpoint={endpoint} />
64
+ {/if}
65
+ </div>
66
+ </div>
src/lib/utils/models.ts CHANGED
@@ -20,4 +20,32 @@ export const IMAGE_GENERATIONS: Array<Model> = [
20
  id: "stabilityai/stable-diffusion-xl-base-1.0",
21
  logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/643feeb67bc3fbde1385cc25/7vmYr2XwVcPtkLzac_jxQ.png?w=200&h=200&f=face"
22
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  ]
 
20
  id: "stabilityai/stable-diffusion-xl-base-1.0",
21
  logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/643feeb67bc3fbde1385cc25/7vmYr2XwVcPtkLzac_jxQ.png?w=200&h=200&f=face"
22
  },
23
+ ]
24
+
25
+ export const TRANSLATION_MODELS: Array<Model> = [
26
+ {
27
+ id: "Helsinki-NLP/opus-mt-fr-en",
28
+ label: "French to English",
29
+ logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/1588345309691-5dd96eb166059660ed1ee413.png?w=200&h=200&f=face",
30
+ }, {
31
+ id: "Helsinki-NLP/opus-mt-en-fr",
32
+ label: "English to French",
33
+ logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/1588345309691-5dd96eb166059660ed1ee413.png?w=200&h=200&f=face",
34
+ }, {
35
+ id: "Helsinki-NLP/opus-mt-de-en",
36
+ label: "German to English",
37
+ logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/1588345309691-5dd96eb166059660ed1ee413.png?w=200&h=200&f=face",
38
+ }, {
39
+ id: "Helsinki-NLP/opus-mt-en-de",
40
+ label: "English to German",
41
+ logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/1588345309691-5dd96eb166059660ed1ee413.png?w=200&h=200&f=face",
42
+ }, {
43
+ id: "Helsinki-NLP/opus-mt-es-en",
44
+ label: "Spanish to English",
45
+ logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/1588345309691-5dd96eb166059660ed1ee413.png?w=200&h=200&f=face",
46
+ }, {
47
+ id: "Helsinki-NLP/opus-mt-en-es",
48
+ label: "English to Spanish",
49
+ logo: "https://aeiljuispo.cloudimg.io/v7/https://cdn-uploads.huggingface.co/production/uploads/1588345309691-5dd96eb166059660ed1ee413.png?w=200&h=200&f=face",
50
+ }
51
  ]
src/lib/utils/type.ts CHANGED
@@ -1,4 +1,5 @@
1
  export interface Model {
2
  id: string;
3
  logo: string;
 
4
  }
 
1
  export interface Model {
2
  id: string;
3
  logo: string;
4
+ label?: string;
5
  }
src/routes/api/translation/+server.ts ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { error, json, type RequestEvent } from '@sveltejs/kit';
2
+ import { env } from '$env/dynamic/private'
3
+
4
+ /** @type {import('./$types').RequestHandler} */
5
+ export async function POST({ request }: RequestEvent) {
6
+ const body = await request?.json().catch(() => {});
7
+
8
+ if (!body?.model) {
9
+ throw error(400, 'missing model value')
10
+ }
11
+
12
+ if (!body?.inputs || body.inputs === null) {
13
+ throw error(400, 'missing inputs value')
14
+ }
15
+
16
+ const response = await fetch(env.SECRET_INFERENCE_API_URL + "/models/" + body.model, {
17
+ method: "POST",
18
+ headers: {
19
+ Authorization: `Bearer ${env.SECRET_HF_TOKEN}`,
20
+ 'Content-Type': 'application/json',
21
+ ['x-use-cache']: "0"
22
+ },
23
+ body: JSON.stringify(body),
24
+ })
25
+ .then((res) => res.json())
26
+ .then((res) => res)
27
+ .catch((error) => {
28
+ return {
29
+ error: error.message,
30
+ }
31
+ })
32
+
33
+ if ("error" in response) {
34
+ error(400, response.error as string)
35
+ }
36
+
37
+ return json(response)
38
+ }
src/routes/image-generation/+page.svelte CHANGED
@@ -1,6 +1,7 @@
1
  <script lang="ts">
2
  import Form from "$lib/components/image-generation/Form.svelte";
3
  import Response from "$lib/components/image-generation/Response.svelte";
 
4
 
5
  let loading: boolean = false;
6
  let data: string | ArrayBuffer | null = ''
@@ -21,6 +22,7 @@
21
  const onchange = (newForm: Record<string, any>) => form = newForm
22
 
23
  const onsubmit = async () => {
 
24
  loading = true
25
  const request = await fetch('/api/image-generation', {
26
  method: 'POST',
@@ -46,12 +48,15 @@
46
  <main class="min-h-screen w-full grid grid-cols-2">
47
  <div class="p-6 lg:p-10 w-full flex flex-col gap-6 lg:overflow-auto lg:h-screen">
48
  <Form form={form} onForm={onchange} />
49
- <div>
50
  <button
51
- class="bg-gradient-to-r from-slate-900/50 to-slate-900 border border-slate-800/40 text-white rounded-lg text-base transition-all duration-200 leading-relaxed outline-none relative py-3 px-6"
52
  disabled={loading}
53
  on:click={onsubmit}
54
  >
 
 
 
55
  Submit
56
  </button>
57
  </div>
 
1
  <script lang="ts">
2
  import Form from "$lib/components/image-generation/Form.svelte";
3
  import Response from "$lib/components/image-generation/Response.svelte";
4
+ import Loading from "$lib/components/Loading.svelte";
5
 
6
  let loading: boolean = false;
7
  let data: string | ArrayBuffer | null = ''
 
22
  const onchange = (newForm: Record<string, any>) => form = newForm
23
 
24
  const onsubmit = async () => {
25
+ if (loading) return
26
  loading = true
27
  const request = await fetch('/api/image-generation', {
28
  method: 'POST',
 
48
  <main class="min-h-screen w-full grid grid-cols-2">
49
  <div class="p-6 lg:p-10 w-full flex flex-col gap-6 lg:overflow-auto lg:h-screen">
50
  <Form form={form} onForm={onchange} />
51
+ <div class="flex justify-end">
52
  <button
53
+ class="w-full bg-gradient-to-r from-slate-900/50 to-slate-900 border border-slate-800/40 text-white rounded-lg text-base transition-all duration-200 leading-relaxed outline-none relative py-3 px-6"
54
  disabled={loading}
55
  on:click={onsubmit}
56
  >
57
+ {#if loading}
58
+ <Loading />
59
+ {/if}
60
  Submit
61
  </button>
62
  </div>
src/routes/text-generation/+page.svelte CHANGED
@@ -1,4 +1,5 @@
1
  <script lang="ts">
 
2
  import Form from "$lib/components/text-generation/Form.svelte";
3
  import Response from "$lib/components/text-generation/Response.svelte";
4
 
@@ -22,6 +23,7 @@
22
  const onchange = (newForm: Record<string, any>) => form = newForm
23
 
24
  const onsubmit = async () => {
 
25
  loading = true
26
  const request = await fetch('/api/text-generation', {
27
  method: 'POST',
@@ -46,6 +48,9 @@
46
  disabled={loading}
47
  on:click={onsubmit}
48
  >
 
 
 
49
  Submit
50
  </button>
51
  </div>
 
1
  <script lang="ts">
2
+ import Loading from "$lib/components/Loading.svelte";
3
  import Form from "$lib/components/text-generation/Form.svelte";
4
  import Response from "$lib/components/text-generation/Response.svelte";
5
 
 
23
  const onchange = (newForm: Record<string, any>) => form = newForm
24
 
25
  const onsubmit = async () => {
26
+ if (loading) return
27
  loading = true
28
  const request = await fetch('/api/text-generation', {
29
  method: 'POST',
 
48
  disabled={loading}
49
  on:click={onsubmit}
50
  >
51
+ {#if loading}
52
+ <Loading />
53
+ {/if}
54
  Submit
55
  </button>
56
  </div>
src/routes/text-generation/translation/+page.svelte CHANGED
@@ -1,3 +1,54 @@
1
- <div>
2
- <p>translation example</p>
3
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script lang="ts">
2
+ import Response from "$lib/components/translation/Response.svelte";
3
+ import Loading from "$lib/components/Loading.svelte";
4
+ import Form from "$lib/components/translation/Form.svelte";
5
+
6
+ let loading: boolean = false;
7
+ let data: Record<string, any> = {}
8
+ let bodyRequest: Record<string, any> = {}
9
+
10
+ let form: Record<string, any> = {
11
+ model: "Helsinki-NLP/opus-mt-fr-en",
12
+ inputs: null,
13
+ }
14
+
15
+ const onchange = (newForm: Record<string, any>) => form = newForm
16
+
17
+ const onsubmit = async () => {
18
+ if (loading) return
19
+ loading = true
20
+ const request = await fetch('/api/text-generation', {
21
+ method: 'POST',
22
+ body: JSON.stringify(form),
23
+ headers: {
24
+ "Content-Type": "application/json"
25
+ }
26
+ })
27
+ const response = await request.clone().json().catch(() => ({}))
28
+ console.log(response)
29
+ data = response
30
+ bodyRequest = form
31
+ loading = false
32
+ }
33
+ </script>
34
+
35
+ <main class="min-h-screen w-full grid grid-cols-1 lg:grid-cols-2">
36
+ <div class="p-6 lg:p-10 w-full flex flex-col gap-6 lg:overflow-auto lg:h-screen">
37
+ <Form form={form} onForm={onchange} />
38
+ <div class="flex justify-end">
39
+ <button
40
+ class="w-full bg-gradient-to-r from-slate-900/50 to-slate-900 border border-slate-800/40 text-white rounded-lg text-base transition-all duration-200 leading-relaxed outline-none relative py-3 px-6"
41
+ disabled={loading}
42
+ on:click={onsubmit}
43
+ >
44
+ {#if loading}
45
+ <Loading />
46
+ {/if}
47
+ Translate
48
+ </button>
49
+ </div>
50
+ </div>
51
+ <div class="border-t lg:border-t-0 lg:border-l border-slate-900 bg-slate-950">
52
+ <Response loading={loading} res={data} body={bodyRequest} form={form} endpoint={form.model} />
53
+ </div>
54
+ </main>