Spaces:
Running
Running
sentiment analysis
Browse files- src/lib/components/sidebar/Sidebar.svelte +5 -5
- src/lib/components/snippets/Curl.svelte +3 -2
- src/lib/components/snippets/Javascript.svelte +3 -2
- src/lib/components/snippets/Python.svelte +3 -2
- src/lib/components/text-analysis/Form.svelte +12 -0
- src/lib/components/text-analysis/Preview.svelte +13 -0
- src/lib/components/text-analysis/Response.svelte +66 -0
- src/lib/components/text-generation/Preview.svelte +18 -5
- src/routes/api/text-analysis/+server.ts +34 -0
- src/routes/text-generation/chat/+page.svelte +0 -3
- src/routes/text-generation/text-analysis/+page.svelte +53 -0
- src/routes/text-generation/translation/+page.svelte +0 -1
src/lib/components/sidebar/Sidebar.svelte
CHANGED
@@ -29,11 +29,11 @@
|
|
29 |
label: "Translation",
|
30 |
icon: "bi:translate",
|
31 |
},
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
];
|
38 |
|
39 |
let open: boolean = false;
|
|
|
29 |
label: "Translation",
|
30 |
icon: "bi:translate",
|
31 |
},
|
32 |
+
{
|
33 |
+
path: "/text-generation/text-analysis",
|
34 |
+
label: "Text Analysis",
|
35 |
+
icon: "carbon:phrase-sentiment",
|
36 |
+
},
|
37 |
];
|
38 |
|
39 |
let open: boolean = false;
|
src/lib/components/snippets/Curl.svelte
CHANGED
@@ -13,11 +13,12 @@
|
|
13 |
let isCopied: boolean = false;
|
14 |
|
15 |
const generateCurlRequestFromEndpoint = (body: Record<string, any>) => {
|
|
|
16 |
const fullpath = `${env.PUBLIC_INFERENCE_API_URL}/models/${endpoint}`;
|
17 |
-
delete
|
18 |
return `curl -X POST "${fullpath}" \\
|
19 |
-H ${JSON.stringify(headers)}
|
20 |
-
-d ${JSON.stringify(
|
21 |
`;
|
22 |
};
|
23 |
|
|
|
13 |
let isCopied: boolean = false;
|
14 |
|
15 |
const generateCurlRequestFromEndpoint = (body: Record<string, any>) => {
|
16 |
+
const b = { ...body };
|
17 |
const fullpath = `${env.PUBLIC_INFERENCE_API_URL}/models/${endpoint}`;
|
18 |
+
delete b.model
|
19 |
return `curl -X POST "${fullpath}" \\
|
20 |
-H ${JSON.stringify(headers)}
|
21 |
+
-d ${JSON.stringify(b)}
|
22 |
`;
|
23 |
};
|
24 |
|
src/lib/components/snippets/Javascript.svelte
CHANGED
@@ -12,15 +12,16 @@
|
|
12 |
let isCopied: boolean = false;
|
13 |
|
14 |
const generateCurlRequestFromEndpoint = (body: Record<string, any>) => {
|
|
|
15 |
const fullpath = `${env.PUBLIC_INFERENCE_API_URL}/models/${endpoint}`;
|
16 |
-
delete
|
17 |
|
18 |
return `const response = await fetch(
|
19 |
"${fullpath}",
|
20 |
{
|
21 |
method: "POST",
|
22 |
headers: ${JSON.stringify(headers)},
|
23 |
-
body: ${JSON.stringify(
|
24 |
}
|
25 |
)`;
|
26 |
};
|
|
|
12 |
let isCopied: boolean = false;
|
13 |
|
14 |
const generateCurlRequestFromEndpoint = (body: Record<string, any>) => {
|
15 |
+
const b = { ...body };
|
16 |
const fullpath = `${env.PUBLIC_INFERENCE_API_URL}/models/${endpoint}`;
|
17 |
+
delete b.model
|
18 |
|
19 |
return `const response = await fetch(
|
20 |
"${fullpath}",
|
21 |
{
|
22 |
method: "POST",
|
23 |
headers: ${JSON.stringify(headers)},
|
24 |
+
body: ${JSON.stringify(b)}
|
25 |
}
|
26 |
)`;
|
27 |
};
|
src/lib/components/snippets/Python.svelte
CHANGED
@@ -12,8 +12,9 @@
|
|
12 |
let isCopied: boolean = false;
|
13 |
|
14 |
const generateCurlRequestFromEndpoint = (body: Record<string, any>) => {
|
|
|
15 |
const fullpath = `${env.PUBLIC_INFERENCE_API_URL}/models/${endpoint}`;
|
16 |
-
delete
|
17 |
|
18 |
const removeEmptyValues = (data: Record<string, any>) => {
|
19 |
const formattedData = { ...data };
|
@@ -30,7 +31,7 @@
|
|
30 |
return formattedData;
|
31 |
};
|
32 |
|
33 |
-
const formattedBody = removeEmptyValues(
|
34 |
return `import requests
|
35 |
response = requests.post(
|
36 |
"${fullpath}",
|
|
|
12 |
let isCopied: boolean = false;
|
13 |
|
14 |
const generateCurlRequestFromEndpoint = (body: Record<string, any>) => {
|
15 |
+
const b = { ...body };
|
16 |
const fullpath = `${env.PUBLIC_INFERENCE_API_URL}/models/${endpoint}`;
|
17 |
+
delete b.model
|
18 |
|
19 |
const removeEmptyValues = (data: Record<string, any>) => {
|
20 |
const formattedData = { ...data };
|
|
|
31 |
return formattedData;
|
32 |
};
|
33 |
|
34 |
+
const formattedBody = removeEmptyValues(b ?? {});
|
35 |
return `import requests
|
36 |
response = requests.post(
|
37 |
"${fullpath}",
|
src/lib/components/text-analysis/Form.svelte
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import Prompt from "$lib/components/Prompt.svelte";
|
3 |
+
|
4 |
+
export let form: Record<string, any>;
|
5 |
+
export let onForm: (form: Record<string, any>) => void;
|
6 |
+
</script>
|
7 |
+
|
8 |
+
<Prompt
|
9 |
+
value={form.inputs}
|
10 |
+
placeholder="Enter your text here"
|
11 |
+
onChange={(inputs) => onForm({ ...form, inputs })}
|
12 |
+
/>
|
src/lib/components/text-analysis/Preview.svelte
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
export let body: Record<string, any>;
|
3 |
+
export let res: Record<string, any>;
|
4 |
+
|
5 |
+
console.log(body, res)
|
6 |
+
|
7 |
+
</script>
|
8 |
+
|
9 |
+
<div class="text-white p-6 font-code text-xs !leading-loose">
|
10 |
+
{#if res?.[0]?.translation_text}
|
11 |
+
{res[0]?.translation_text}
|
12 |
+
{/if}
|
13 |
+
</div>
|
src/lib/components/text-analysis/Response.svelte
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import Icon from '@iconify/svelte';
|
3 |
+
import Highlight, { LineNumbers } 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/components/text-generation/Preview.svelte
CHANGED
@@ -2,11 +2,24 @@
|
|
2 |
export let body: Record<string, any>;
|
3 |
export let res: Record<string, any>;
|
4 |
|
5 |
-
|
|
|
|
|
|
|
|
|
6 |
</script>
|
7 |
|
8 |
-
<div class="text-white p-6 font-code text-xs !leading-loose">
|
9 |
-
{
|
10 |
-
{
|
11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
</div>
|
|
|
2 |
export let body: Record<string, any>;
|
3 |
export let res: Record<string, any>;
|
4 |
|
5 |
+
|
6 |
+
$: progressions = res?.flat()
|
7 |
+
|
8 |
+
|
9 |
+
$: console.log(progressions, body)
|
10 |
</script>
|
11 |
|
12 |
+
<div class="text-white p-6 font-code text-xs !leading-loose grid grid-cols-1 gap-3 w-full max-w-lg">
|
13 |
+
"{body?.inputs}"
|
14 |
+
{#each progressions as { label, score }}
|
15 |
+
<div>
|
16 |
+
<div class="flex items-center justify-between mb-1">
|
17 |
+
<p class="text-blue-500">{label}</p>
|
18 |
+
<p class="text-green-500 text-xs">{score}</p>
|
19 |
+
</div>
|
20 |
+
<div class="w-full rounded-full bg-slate-800 h-[8px]">
|
21 |
+
<div class="h-full rounded-full bg-gradient-to-r from-blue-500 to-green-500" style="width: {score * 100}%"></div>
|
22 |
+
</div>
|
23 |
+
</div>
|
24 |
+
{/each}
|
25 |
</div>
|
src/routes/api/text-analysis/+server.ts
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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?.inputs || body.inputs === null) {
|
9 |
+
throw error(400, 'missing inputs value')
|
10 |
+
}
|
11 |
+
|
12 |
+
const response = await fetch(env.SECRET_INFERENCE_API_URL + "/models/lxyuan/distilbert-base-multilingual-cased-sentiments-student", {
|
13 |
+
method: "POST",
|
14 |
+
headers: {
|
15 |
+
Authorization: `Bearer ${env.SECRET_HF_TOKEN}`,
|
16 |
+
'Content-Type': 'application/json',
|
17 |
+
['x-use-cache']: "0"
|
18 |
+
},
|
19 |
+
body: JSON.stringify(body),
|
20 |
+
})
|
21 |
+
.then((res) => res.json())
|
22 |
+
.then((res) => res)
|
23 |
+
.catch((error) => {
|
24 |
+
return {
|
25 |
+
error: error.message,
|
26 |
+
}
|
27 |
+
})
|
28 |
+
|
29 |
+
if ("error" in response) {
|
30 |
+
error(400, response.error as string)
|
31 |
+
}
|
32 |
+
|
33 |
+
return json(response)
|
34 |
+
}
|
src/routes/text-generation/chat/+page.svelte
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
<div>
|
2 |
-
<p>chat example</p>
|
3 |
-
</div>
|
|
|
|
|
|
|
|
src/routes/text-generation/text-analysis/+page.svelte
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<script lang="ts">
|
2 |
+
import Response from "$lib/components/text-analysis/Response.svelte";
|
3 |
+
import Loading from "$lib/components/Loading.svelte";
|
4 |
+
import Form from "$lib/components/text-analysis/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 |
+
inputs: null,
|
12 |
+
model: "lxyuan/distilbert-base-multilingual-cased-sentiments-student"
|
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-analysis', {
|
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 |
+
data = response
|
29 |
+
bodyRequest = form
|
30 |
+
loading = false
|
31 |
+
}
|
32 |
+
</script>
|
33 |
+
|
34 |
+
<main class="min-h-screen w-full grid grid-cols-1 lg:grid-cols-2">
|
35 |
+
<div class="p-6 lg:p-10 w-full flex flex-col gap-6 lg:overflow-auto lg:h-screen">
|
36 |
+
<Form form={form} onForm={onchange} />
|
37 |
+
<div class="flex justify-end">
|
38 |
+
<button
|
39 |
+
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"
|
40 |
+
disabled={loading}
|
41 |
+
on:click={onsubmit}
|
42 |
+
>
|
43 |
+
{#if loading}
|
44 |
+
<Loading />
|
45 |
+
{/if}
|
46 |
+
Translate
|
47 |
+
</button>
|
48 |
+
</div>
|
49 |
+
</div>
|
50 |
+
<div class="border-t lg:border-t-0 lg:border-l border-slate-900 bg-slate-950">
|
51 |
+
<Response loading={loading} res={data} body={bodyRequest} form={form} endpoint={form.model} />
|
52 |
+
</div>
|
53 |
+
</main>
|
src/routes/text-generation/translation/+page.svelte
CHANGED
@@ -25,7 +25,6 @@
|
|
25 |
}
|
26 |
})
|
27 |
const response = await request.clone().json().catch(() => ({}))
|
28 |
-
console.log(response)
|
29 |
data = response
|
30 |
bodyRequest = form
|
31 |
loading = false
|
|
|
25 |
}
|
26 |
})
|
27 |
const response = await request.clone().json().catch(() => ({}))
|
|
|
28 |
data = response
|
29 |
bodyRequest = form
|
30 |
loading = false
|