add UI test for codegen (#244)

Signed-off-by: Yue, Wenjiao <wenjiao.yue@intel.com>
Signed-off-by: Sun, Xuehao <xuehao.sun@intel.com>
This commit is contained in:
Sun, Xuehao
2024-05-31 21:22:59 +08:00
committed by GitHub
parent 3237ee4c58
commit dbee190e64
32 changed files with 1144 additions and 246 deletions

View File

@@ -0,0 +1,10 @@
[*]
indent_style = tab
[package.json]
indent_style = space
indent_size = 2
[*.md]
indent_style = space
indent_size = 2

View File

@@ -1 +1 @@
BASIC_URL = 'http://xxx.xxx.xxx.xxx:yyyy'
BASIC_URL = 'http://backend_address:7778/v1/codegen'

View File

@@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
module.exports = {
root: true,
parser: "@typescript-eslint/parser",
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
plugins: ["svelte3", "@typescript-eslint", "neverthrow"],
ignorePatterns: ["*.cjs"],
overrides: [{ files: ["*.svelte"], processor: "svelte3/svelte3" }],
settings: {
"svelte3/typescript": () => require("typescript"),
},
parserOptions: {
sourceType: "module",
ecmaVersion: 2020,
},
env: {
browser: true,
es2017: true,
node: true,
},
};

View File

@@ -0,0 +1,13 @@
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock

View File

@@ -0,0 +1,13 @@
{
"pluginSearchDirs": [
"."
],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}

View File

@@ -18,7 +18,7 @@ Here're some of the project's features:
3. Modify the required .env variables.
```
BASIC_URL = ''
BASE_URL = ''
```
4. Execute `npm install` to install the corresponding dependencies.

View File

@@ -1,54 +1,62 @@
{
"name": "doc-summary",
"name": "sveltekit-auth-example",
"version": "0.0.1",
"private": true,
"scripts": {
"dev": "vite dev",
"build": "vite build && npm run package",
"build": "vite build",
"preview": "vite preview",
"package": "svelte-kit sync && svelte-package && publint",
"prepublishOnly": "npm run package",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
},
"exports": {
".": {
"types": "./dist/index.d.ts",
"svelte": "./dist/index.js"
}
},
"files": [
"dist",
"!dist/**/*.test.*",
"!dist/**/*.spec.*"
],
"peerDependencies": {
"svelte": "^4.0.0"
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check . && eslint .",
"format": "prettier --write ."
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/kit": "^2.0.0",
"@sveltejs/package": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^3.0.0",
"autoprefixer": "^10.4.16",
"flowbite": "^2.3.0",
"flowbite-svelte": "^0.44.24",
"flowbite-svelte-icons": "^1.4.5",
"postcss": "^8.4.32",
"postcss-load-config": "^5.0.2",
"publint": "^0.1.9",
"svelte": "^4.2.7",
"svelte-check": "^3.6.0",
"tailwindcss": "^3.3.6",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^5.0.11"
"@fortawesome/free-solid-svg-icons": "6.2.0",
"@playwright/test": "^1.44.1",
"@sveltejs/adapter-auto": "^1.0.0-next.75",
"@sveltejs/kit": "^1.20.1",
"@tailwindcss/typography": "0.5.7",
"@types/debug": "4.1.7",
"@typescript-eslint/eslint-plugin": "^5.27.0",
"@typescript-eslint/parser": "^5.27.0",
"autoprefixer": "^10.4.7",
"daisyui": "3.5.1",
"date-picker-svelte": "^2.6.0",
"debug": "4.3.4",
"eslint": "^8.16.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-neverthrow": "1.1.4",
"eslint-plugin-svelte3": "^4.0.0",
"postcss": "^8.4.23",
"postcss-load-config": "^4.0.1",
"postcss-preset-env": "^8.3.2",
"prettier": "^2.8.8",
"prettier-plugin-svelte": "^2.7.0",
"prettier-plugin-tailwindcss": "^0.3.0",
"svelte": "^3.59.1",
"svelte-check": "^2.7.1",
"svelte-fa": "3.0.3",
"svelte-highlight": "^7.6.1",
"svelte-loading-spinners": "^0.3.6",
"svelte-preprocess": "^4.10.7",
"tailwindcss": "^3.1.5",
"tslib": "^2.3.1",
"typescript": "^4.7.4",
"vite": "^4.3.9"
},
"svelte": "./dist/index.js",
"types": "./dist/index.d.ts",
"type": "module",
"dependencies": {
"highlight.js": "^11.9.0",
"date-fns": "^2.30.0",
"driver.js": "^1.3.0",
"flowbite-svelte": "^0.38.5",
"flowbite-svelte-icons": "^1.4.0",
"fuse.js": "^6.6.2",
"lodash": "^4.17.21",
"marked": "^12.0.2",
"ramda": "^0.29.0",
"sse.js": "^0.6.1",
"svelte-notifications": "^0.9.98"
"svelte-notifications": "^0.9.98",
"svrollbar": "^0.12.0"
}
}

View File

@@ -0,0 +1,54 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
import { defineConfig, devices } from "@playwright/test";
/**
* Read environment variables from file.
* https://github.com/motdotla/dotenv
*/
// require('dotenv').config();
/**
* See https://playwright.dev/docs/test-configuration.
*/
export default defineConfig({
testDir: "./tests",
/* Maximum time one test can run for. */
timeout: 30 * 1000,
expect: {
/**
* Maximum time expect() should wait for the condition to be met.
* For example in `await expect(locator).toHaveText();`
*/
timeout: 5000,
},
/* Run tests in files in parallel */
fullyParallel: true,
/* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI,
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: [["html", { open: "never" }]],
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
actionTimeout: 0,
/* Base URL to use in actions like `await page.goto('/')`. */
baseURL: "http://localhost:5173",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
},
/* Configure projects for major browsers */
projects: [
{
name: "webkit",
use: { ...devices["Desktop Safari"] },
},
],
});

View File

@@ -1,13 +1,27 @@
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const tailwindcss = require("tailwindcss");
const autoprefixer = require("autoprefixer");
const config = {
plugins: [
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
tailwindcss(),
//But others, like autoprefixer, need to run after,
autoprefixer,
],
plugins: [
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
tailwindcss(),
//But others, like autoprefixer, need to run after,
autoprefixer,
],
};
module.exports = config;

View File

@@ -1,16 +1,19 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
// interface Locals {}
// interface PageData {}
// interface PageState {}
// interface Platform {}
}
// See: https://kit.svelte.dev/docs/types#app
// import { Result} from "neverthrow";
interface Window {
deviceType: string;
}
export {};

View File

@@ -1,17 +1,29 @@
<!--
Copyright (C) 2024 Intel Corporation
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div>%sveltekit.body%</div>
</body>
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
<body>
<div class="h-full w-full">%sveltekit.body%</div>
</body>
</html>

View File

@@ -0,0 +1,116 @@
/* Write your global styles here, in PostCSS syntax */
@tailwind base;
@tailwind components;
@tailwind utilities;
/* app.postcss */
html {
font-size: 16px;
}
@media screen and (min-width: 576px) and (max-width: 1440px) {
html {
font-size: 16px;
}
}
@media screen and (min-width: 1441px) {
html {
font-size: 23px;
}
}
html, body {
height: 100%;
}
:global(.svlr-contents) {
height: 100%;
}
.row::-webkit-scrollbar {
display: none;
}
.row {
scrollbar-width: none; /* Firefox */
-ms-overflow-style: none; /* IE/Edge */
}
.row::-webkit-scrollbar {
display: none; /* WebKit browsers */
}
.btn {
@apply flex-nowrap;
}
a.btn {
@apply no-underline;
}
.input {
@apply text-base;
}
.bg-dark-blue {
background-color: #004a86;
}
.bg-light-blue {
background-color: #0068b5;
}
.bg-turquoise {
background-color: #00a3f6;
}
.bg-header {
background-color: #ffffff;
}
.bg-button {
background-color: #0068b5;
}
.bg-title {
background-color: #f7f7f7;
}
.text-header {
color: #0068b5;
}
.text-button {
color: #252e47;
}
.text-title-color {
color: rgb(38,38,38);
}
.bg-footer {
background-color: #e7e7e7;
}
.bg-light-green {
background-color: #d7f3a1;
}
.bg-purple {
background-color: #653171;
}
.bg-dark-blue {
background-color: #224678;
}
.border-input-color {
border-color: #605e5c;
}
.w-12\/12 {
width: 100%
}

View File

@@ -0,0 +1,38 @@
<!--
Copyright (c) 2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script lang="ts">
export let overrideClasses = "";
const classes = overrideClasses ? overrideClasses : `w-5 h-5 text-gray-400`;
</script>
<svg
t="1708926517502"
class={classes}
viewBox="0 0 1024 1024"
version="1.1"
xmlns="http://www.w3.org/2000/svg"
p-id="4586"
id="mx_n_1708926517503"
width="200"
height="200"
><path
d="M0 1024l106.496-474.112 588.8-36.864-588.8-39.936-106.496-473.088 1024 512z"
p-id="4587"
fill="#0068b5"
/></svg
>

View File

@@ -0,0 +1,94 @@
.driverjs-theme {
background: transparent;
color: #fff;
box-shadow: none;
padding: 0;
}
.driver-popover-arrow {
border: 10px solid transparent;
animation: blink 1s 3 steps(1);
}
@keyframes blink {
0% {
opacity: 1;
}
50% {
opacity: 0.2;
}
100% {
opacity: 1;
}
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-left.driver-popover-arrow {
border-left-color: #174ed1;
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-right.driver-popover-arrow {
border-right-color: #174ed1;
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-top.driver-popover-arrow {
border-top-color: #174ed1;
}
.driver-popover.driverjs-theme .driver-popover-arrow-side-bottom.driver-popover-arrow {
border-bottom-color: #174ed1;
}
.driver-popover-footer {
background: transparent;
color: #fff;
}
.driver-popover-title {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
.driver-popover-title,
.driver-popover-description {
display: block;
padding: 15px 15px 7px 15px;
background: #174ed1;
border: none;
}
.driver-popover-close-btn {
color: #fff;
}
.driver-popover-footer button:hover,
.driver-popover-footer button:focus {
background: #174ed1;
color: #fff;
}
.driver-popover-description {
padding: 5px 15px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.driver-popover-title[style*="block"] + .driver-popover-description {
margin: 0;
}
.driver-popover-progress-text {
color: #fff;
}
.driver-popover-footer button {
background: #174ed1;
border: 2px #174ed1 dashed;
color: #fff;
border-radius: 50%;
text-shadow: none;
}
.driver-popover-close-btn:hover,
.driver-popover-close-btn:focus {
color: #fff;
}
.driver-popover-navigation-btns button + button {
margin-left: 10px;
}

View File

@@ -0,0 +1,136 @@
<!--
Copyright (c) 2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script lang="ts">
import Highlight, { LineNumbers } from "svelte-highlight";
import typescript from "svelte-highlight/languages/typescript";
import c from "svelte-highlight/languages/c";
import cpp from "svelte-highlight/languages/cpp";
import csharp from "svelte-highlight/languages/csharp";
import go from "svelte-highlight/languages/go";
import java from "svelte-highlight/languages/java";
import python from "svelte-highlight/languages/python";
import javascript from "svelte-highlight/languages/javascript";
import swift from "svelte-highlight/languages/swift";
import ruby from "svelte-highlight/languages/ruby";
import rust from "svelte-highlight/languages/rust";
import php from "svelte-highlight/languages/php";
import kotlin from "svelte-highlight/languages/kotlin";
import objectivec from "svelte-highlight/languages/objectivec";
import perl from "svelte-highlight/languages/perl";
import matlab from "svelte-highlight/languages/matlab";
import r from "svelte-highlight/languages/r";
import lua from "svelte-highlight/languages/lua";
import bash from "svelte-highlight/languages/bash";
import sql from "svelte-highlight/languages/sql";
import { marked } from "marked";
export let label = "";
export let output = "";
export let languages = "Python";
export let isCode = false;
let copyText = "copy";
const languagesTag = {
Typescript: typescript,
Python: python,
C: c,
Cpp: cpp,
Csharp: csharp,
Go: go,
Java: java,
Javascript: javascript,
Swift: swift,
Ruby: ruby,
Rust: rust,
Php: php,
Kotlin: kotlin,
Objectivec: objectivec,
Perl: perl,
Matlab: matlab,
R: r,
Lua: lua,
Bash: bash,
Sql: sql,
} as { [key: string]: any };
function copyToClipboard(text) {
const textArea = document.createElement("textarea");
textArea.value = text;
document.body.appendChild(textArea);
textArea.select();
document.execCommand("copy");
document.body.removeChild(textArea);
}
function handelCopy() {
copyToClipboard(output);
copyText = "copied!";
setTimeout(() => {
copyText = "copy";
}, 1000);
}
</script>
<div class="flex w-full flex-col" data-testid="code-output">
<span
class=" mb-2 flex h-[3rem] w-full items-center justify-center bg-[#5856D6] px-8 py-2 text-center text-[0.89rem] uppercase leading-tight opacity-80"
>{label}</span
>
<div
class="flex justify-end border-2 border-none border-b-gray-800 bg-[#1C1C1C] px-3 text-white"
>
<button
class="rounded border border-none py-1 text-[0.8rem] text-[#abb2bf]"
on:click={() => {
handelCopy();
}}>{copyText}</button
>
</div>
<div
class="code-format-style hiddenScroll h-[22rem] divide-y overflow-auto bg-[#011627]"
>
{#if isCode}
<Highlight language={python} code={output} let:highlighted>
<LineNumbers {highlighted} wrapLines hideBorder />
</Highlight>
{:else}
<div class="bg-[#282c34] text-[#abb2bf]">
{@html marked(output)}
</div>
{/if}
</div>
</div>
<style>
.hiddenScroll::-webkit-scrollbar {
display: none;
}
.hiddenScroll {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.code-format-style {
resize: none;
font-size: 16px;
border: solid rgba(128, 0, 128, 0) 4px;
box-shadow: 0 0 8px rgba(0, 0, 0, 0.19);
transition: 0.1s linear;
}
</style>

View File

@@ -0,0 +1,22 @@
<!--
Copyright (C) 2024 Intel Corporation
SPDX-License-Identifier: Apache-2.0
-->
<script>
</script>
<header
class="sticky top-0 z-40 flex-none w-full mx-auto bg-[#0054ae] border-b border-gray-200 dark:border-gray-600 dark:bg-gray-800"
>
<nav
class="bg-[#0054ae] dark:bg-gray-800 text-gray-500 dark:text-gray-400 border-gray-200 dark:border-gray-700 divide-gray-200 dark:divide-gray-700 px-2 sm:px-4 w-full py-3"
>
<div class="mx-auto flex flex-wrap justify-between items-center w-full">
<span
class="self-center whitespace-nowrap text-xl font-semibold text-white ml-4"
data-svelte-h="svelte-1hbktnk">Code Gen</span
>
</div>
</nav>
</header>

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { env } from "$env/dynamic/public";
import { SSE } from "sse.js";
const BASE_URL = env.BASIC_URL;
export async function fetchTextStream(query: string) {
let payload = {};
let url = "";
payload = {
messages: query,
};
url = `${BASE_URL}`;
return new SSE(url, {
headers: { "Content-Type": "application/json" },
payload: JSON.stringify(payload),
});
}

View File

@@ -7,42 +7,42 @@ import { env } from "$env/dynamic/public";
const BASIC_URL = env.BASIC_URL;
async function fetchPostRes(url, init) {
try {
const response = await fetch(url, init);
if (!response.ok) throw response.status;
return await response.json();
} catch (error) {
console.error("network error: ", error);
return undefined;
}
try {
const response = await fetch(url, init);
if (!response.ok) throw response.status;
return await response.json();
} catch (error) {
console.error("network error: ", error);
return undefined;
}
}
export async function fetchKnowledgeBaseId(file: Blob, fileName: string) {
const url = `${BASIC_URL}/doc_upload`;
const formData = new FormData();
formData.append("file", file, fileName);
const url = `${BASIC_URL}/doc_upload`;
const formData = new FormData();
formData.append("file", file, fileName);
const init: RequestInit = {
method: "POST",
body: formData,
};
const init: RequestInit = {
method: "POST",
body: formData,
};
return fetchPostRes(url, init);
return fetchPostRes(url, init);
}
export async function fetchTextStream(query: string, urlSuffix: string, params: string) {
let payload = {};
if (params === "doc_id") {
payload = { doc_id: query };
} else if (params === "text") {
payload = { text: query };
}
let payload = {};
if (params === "doc_id") {
payload = { doc_id: query };
} else if (params === "text") {
payload = { text: query };
}
let url = `${BASIC_URL}${urlSuffix}`;
console.log("url", url);
let url = `${BASIC_URL}${urlSuffix}`;
console.log("url", url);
return new SSE(url, {
headers: { "Content-Type": "application/json" },
payload: JSON.stringify(payload),
});
return new SSE(url, {
headers: { "Content-Type": "application/json" },
payload: JSON.stringify(payload),
});
}

View File

@@ -2,14 +2,14 @@
// SPDX-License-Identifier: Apache-2.0
export function scrollToBottom(scrollToDiv: HTMLElement) {
if (scrollToDiv) {
setTimeout(
() =>
scrollToDiv.scroll({
behavior: "auto",
top: scrollToDiv.scrollHeight,
}),
100,
);
}
if (scrollToDiv) {
setTimeout(
() =>
scrollToDiv.scroll({
behavior: "auto",
top: scrollToDiv.scrollHeight,
}),
100,
);
}
}

View File

@@ -0,0 +1,48 @@
<!--
Copyright (c) 2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<div
class="mb-6 flex items-center justify-center self-center bg-black text-sm text-gray-500"
/>
<div class="flex items-center justify-center gap-3">
<div class="relative inline-flex">
<div class="h-2 w-2 rounded-full bg-blue-300" />
<div
class="absolute left-0 top-0 h-2 w-2 animate-[ping_1s_infinite_100ms] rounded-full bg-blue-300"
/>
<div
class="duration-800 absolute left-0 top-0 h-2 w-2 animate-pulse rounded-full bg-blue-300"
/>
</div>
<div class="relative inline-flex">
<div class="h-2 w-2 rounded-full bg-blue-300" />
<div
class="absolute left-0 top-0 h-2 w-2 animate-[ping_1s_infinite_300ms] rounded-full bg-blue-300"
/>
<div
class="absolute left-0 top-0 h-2 w-2 animate-pulse rounded-full bg-blue-300"
/>
</div>
<div class="relative inline-flex">
<div class="h-2 w-2 rounded-full bg-blue-300" />
<div
class="absolute left-0 top-0 h-2 w-2 animate-[ping_1s_infinite_500ms] rounded-full bg-blue-300"
/>
<div
class="absolute left-0 top-0 h-2 w-2 animate-pulse rounded-full bg-blue-300"
/>
</div>
</div>

View File

@@ -0,0 +1,48 @@
<!--
Copyright (c) 2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script lang="ts">
import { Svroller } from "svrollbar";
export let className: string = "";
export let classLayout: string = "";
export let alwaysVisible = true;
</script>
<div class={className}>
<Svroller height="100%" width="100%" {alwaysVisible}>
<div class={classLayout}>
<slot></slot>
</div>
</Svroller>
</div>
<style>
:global(.svlr-contents) {
height: 100%;
}
.row::-webkit-scrollbar {
display: none;
}
.row {
scrollbar-width: none;
}
.row {
-ms-overflow-style: none;
}
</style>

View File

@@ -1,14 +1,32 @@
<!--
Copyright (C) 2024 Intel Corporation
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script>
import "../app.pcss";
import Notifications from "svelte-notifications";
import "tailwindcss/tailwind.css";
import "../app.postcss";
import Notifications from "svelte-notifications";
import Header from "$lib/modules/frame/header.svelte";
import atomOneDark from "svelte-highlight/styles/atom-one-dark";
</script>
<svelte:head>
{@html atomOneDark}
</svelte:head>
<Notifications>
<slot />
<Header />
<slot />
</Notifications>

View File

@@ -1,85 +1,115 @@
<!--
Copyright (C) 2024 Intel Corporation
SPDX-License-Identifier: Apache-2.0
Copyright (c) 2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<script lang="ts">
import Header from "$lib/header.svelte";
import InputAirPlane from "$lib/InputAirPlane.svelte";
import Doc from "$lib/doc.svelte";
import Summary from "$lib/summary.svelte";
import { fetchTextStream } from "$lib/shared/Network.js";
import { loading } from "$lib/shared/Store.js";
import { onMount } from "svelte";
import { scrollToBottom } from "$lib/shared/Utils.js";
export let data;
import { fetchTextStream } from "$lib/network/chat/Network";
import LoadingAnimation from "$lib/shared/components/loading/Loading.svelte";
import "driver.js/dist/driver.css";
import "$lib/assets/layout/css/driver.css";
import PaperAirplane from "$lib/assets/chat/svelte/PaperAirplane.svelte";
import Output from "$lib/modules/chat/Output.svelte";
let messages = "";
let scrollToDiv: HTMLDivElement;
let code_output: string = "";
let query: string = "";
let loading: boolean = false;
let deleteFlag: boolean = false;
onMount(() => {
scrollToDiv = document.querySelector("#editor")!;
console.log("scrollToDiv", scrollToDiv);
});
const callTextStream = async (query: string) => {
loading = true;
code_output = "";
const eventSource = await fetchTextStream(query);
const callTextStream = async (
query: string,
urlSuffix: string,
params: string
) => {
messages = "";
const eventSource = await fetchTextStream(query, urlSuffix, params);
eventSource.addEventListener("message", (e: any) => {
let Msg = e.data;
if (Msg !== "[DONE]") {
let res = JSON.parse(Msg);
let logs = res.ops;
logs.forEach((log: { op: string; path: string; value: any }) => {
if (log.op === "add") {
if (
log.path.endsWith("/streamed_output/-") &&
typeof log.value === "string"
) {
messages += log.value;
scrollToBottom(scrollToDiv);
}
}
});
} else {
loading.set(false);
scrollToBottom(scrollToDiv);
}
});
eventSource.stream();
};
async function handleGenerateSummary(e) {
if (e.detail.mode === "file") {
await callTextStream(e.detail.value, "/file_summarize", "doc_id");
} else if (e.detail.mode === "text") {
await callTextStream(e.detail.value, "/text_summarize", "text");
}
}
function handleClearMsg(e) {
if (e.detail.status) {
messages = "";
}
}
function handleSubmit() {
}
eventSource.addEventListener("message", (e: any) => {
let Msg = e.data;
console.log("Msg", Msg);
if (Msg.startsWith("b")) {
const trimmedData = Msg.slice(2, -1);
if (trimmedData.includes("'''")) {
deleteFlag = true;
} else if (deleteFlag && trimmedData.includes("\\n")) {
deleteFlag = false;
} else if (trimmedData !== "</s>" && !deleteFlag) {
code_output += trimmedData.replace(/\\n/g, "\n");
}
} else if (Msg === "[DONE]") {
deleteFlag = false;
loading = false;
query = '';
}
});
eventSource.stream();
};
const handleTextSubmit = async () => {
await callTextStream(query);
};
</script>
<div class="h-full">
<Header />
<div class="w-[80%] mx-auto">
<InputAirPlane on:handelSubmit={handleSubmit}/>
<Summary chatMessage={messages} />
</div>
<pre><code>{@html `<span class="hljs"></span>`}</code></pre>
<div class="flex grow flex-col text-white">
<div class="relative h-full items-center gap-5 bg-fixed sm:flex">
<div
class="relative mx-auto flex h-full w-full flex-col items-center sm:mt-0 sm:w-[70%]"
>
<div
class="fixed relative flex w-full flex-col items-center justify-between bg-white p-2 pb-0"
>
<div class="relative my-4 flex w-full flex-row justify-center">
<div class="relative w-full focus:border-none">
<input
class="block w-full break-words border-0 border-b-2 border-gray-300 px-1 py-4 pl-4 pr-20 text-xs
text-gray-900 focus:border-gray-300 focus:ring-0 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
type="text"
data-testid="code-input"
placeholder="Enter prompt here"
disabled={loading}
maxlength="1200"
bind:value={query}
on:keydown={(event) => {
if (event.key === "Enter" && !event.shiftKey && query) {
event.preventDefault();
handleTextSubmit();
}
}}
/>
<button
on:click={() => {
if (query) {
handleTextSubmit();
}
}}
type="submit"
id="send"
class="absolute bottom-2.5 end-2.5 px-4 py-2 text-sm font-medium text-white dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
><PaperAirplane /></button
>
</div>
</div>
</div>
<div class="mb-4 flex h-full w-full flex-col items-center">
{#if code_output !== ""}
<div class="w-full items-center gap-4">
<Output label="Generated results" output={code_output} />
</div>
{/if}
{#if loading}
<LoadingAnimation />
{/if}
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,13 @@
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

View File

@@ -1,24 +1,38 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import adapter from "@sveltejs/adapter-auto";
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
import preprocess from "svelte-preprocess";
import postcssPresetEnv from "postcss-preset-env";
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: [vitePreprocess({})],
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: preprocess({
sourceMap: true,
postcss: {
plugins: [postcssPresetEnv({ features: { "nesting-rules": true } })],
},
}),
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter(),
env: {
publicPrefix: "",
},
},
kit: {
adapter: adapter(),
env: {
publicPrefix: "",
},
},
};
export default config;

View File

@@ -1,29 +1,43 @@
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const config = {
content: ["./src/**/*.{html,js,svelte,ts}", "./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}"],
content: ["./src/**/*.{html,js,svelte,ts}", "./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}"],
plugins: [require("flowbite/plugin")],
plugins: [require("flowbite/plugin")],
darkMode: "class",
darkMode: "class",
theme: {
extend: {
colors: {
// flowbite-svelte
primary: {
50: "#f2f8ff",
100: "#eef5ff",
200: "#deecff",
300: "#cce2ff",
400: "#add0ff",
500: "#5da2fe",
600: "#2f81ef",
700: "#2780eb",
800: "#226fcc",
900: "#1b5aa5",
},
},
},
},
theme: {
extend: {
colors: {
// flowbite-svelte
primary: {
50: "#FFF5F2",
100: "#FFF1EE",
200: "#FFE4DE",
300: "#FFD5CC",
400: "#FFBCAD",
500: "#FE795D",
600: "#EF562F",
700: "#EB4F27",
800: "#CC4522",
900: "#A5371B",
},
},
},
},
};
module.exports = config;

View File

@@ -0,0 +1,31 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
import { test, expect, type Page } from "@playwright/test";
// Initialization before each test
test.beforeEach(async ({ page }) => {
await page.goto("/");
});
// Constants definition
const CHAT_ITEMS = [
"Implement a high-level API for a TODO list application. The API takes as input an operation request and updates the TODO list in place. If the request is invalid, raise an exception.",
];
// Helper function: Enter message to chat
async function enterMessageToChat(page: Page, message: string) {
await page.getByTestId("code-input").click();
await page.getByTestId("code-input").fill(message);
await page.getByTestId("code-input").press("Enter");
await page.waitForTimeout(10000);
await expect(page.getByTestId("code-output")).toContainText("copy");
}
// Test description: New Code Gen
test.describe("New Code Gen", () => {
// Test: Enter message to summary
test("should enter message to generate code gen", async ({ page }) => {
await enterMessageToChat(page, CHAT_ITEMS[0]);
});
});

View File

@@ -1,15 +1,13 @@
{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"module": "NodeNext",
"moduleResolution": "NodeNext"
}
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true
}
}

View File

@@ -1,9 +1,23 @@
// Copyright (C) 2024 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2024 Intel Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
import type { UserConfig } from "vite";
export default defineConfig({
plugins: [sveltekit()],
});
const config: UserConfig = {
plugins: [sveltekit()],
server: {},
};
export default config;

View File

@@ -36,6 +36,8 @@ function start_services() {
export LLM_SERVICE_HOST_IP=${ip_address}
export BACKEND_SERVICE_ENDPOINT="http://${ip_address}:7778/v1/codegen"
sed -i "s/backend_address/$ip_address/g" $WORKPATH/docker/ui/svelte/.env
# Start Docker Containers
# TODO: Replace the container name with a test-specific name
docker compose -f docker_compose.yaml up -d
@@ -101,6 +103,31 @@ function validate_megaservice() {
}
function validate_frontend() {
cd $WORKPATH/docker/ui/svelte
local conda_env_name="CodeGen_e2e"
export PATH=${HOME}/miniforge3/bin/:$PATH
conda remove -n ${conda_env_name} --all -y
conda create -n ${conda_env_name} python=3.12 -y
source activate ${conda_env_name}
sed -i "s/localhost/$ip_address/g" playwright.config.ts
conda install -c conda-forge nodejs -y && npm install && npm ci && npx playwright install --with-deps
node -v && npm -v && pip list
exit_status=0
npx playwright test || exit_status=$?
if [ $exit_status -ne 0 ]; then
echo "[TEST INFO]: ---------frontend test failed---------"
exit $exit_status
else
echo "[TEST INFO]: ---------frontend test passed---------"
fi
}
function stop_docker() {
cd $WORKPATH/docker/gaudi
container_list=$(cat docker_compose.yaml | grep container_name | cut -d':' -f2)
@@ -119,6 +146,7 @@ function main() {
validate_microservices
validate_megaservice
validate_frontend
stop_docker
echo y | docker system prune

View File

@@ -34,6 +34,8 @@ function start_services() {
export LLM_SERVICE_HOST_IP=${ip_address}
export BACKEND_SERVICE_ENDPOINT="http://${ip_address}:7778/v1/codegen"
sed -i "s/backend_address/$ip_address/g" $WORKPATH/docker/ui/svelte/.env
# Start Docker Containers
# TODO: Replace the container name with a test-specific name
docker compose -f docker_compose.yaml up -d
@@ -99,6 +101,32 @@ function validate_megaservice() {
}
function validate_frontend() {
cd $WORKPATH/docker/ui/svelte
local conda_env_name="CodeGen_e2e"
export PATH=${HOME}/miniforge3/bin/:$PATH
conda remove -n ${conda_env_name} --all -y
conda create -n ${conda_env_name} python=3.12 -y
source activate ${conda_env_name}
sed -i "s/localhost/$ip_address/g" playwright.config.ts
conda install -c conda-forge nodejs -y && npm install && npm ci && npx playwright install --with-deps
node -v && npm -v && pip list
exit_status=0
npx playwright test || exit_status=$?
if [ $exit_status -ne 0 ]; then
echo "[TEST INFO]: ---------frontend test failed---------"
exit $exit_status
else
echo "[TEST INFO]: ---------frontend test passed---------"
fi
}
function stop_docker() {
cd $WORKPATH/docker/xeon
container_list=$(cat docker_compose.yaml | grep container_name | cut -d':' -f2)
@@ -117,6 +145,7 @@ function main() {
validate_microservices
validate_megaservice
validate_frontend
stop_docker
echo y | docker system prune