code-gen-react-ui (#417)
* CodeGen: Manifest to deploy CodeGen with ReactUI into Kubernetes Include manifest to deploy CodeGen pipeline with ReactUI into Kubernetes. Include as well README file for the steps. Signed-off-by: Yeoh, Hoong Tee <hoong.tee.yeoh@intel.com> * code-gen-react-ui Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * made changes as per PR suggestions Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updated readme Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * update base image Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * updated codegn dockerfile react Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * updated wait time Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * updated as per PR comments Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * aded react ui in gaudi test file Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * fixed PR comments Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * added docker pull for text-generation-model Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> * removed unused files Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> --------- Signed-off-by: Yeoh, Hoong Tee <hoong.tee.yeoh@intel.com> Signed-off-by: jaswanth8888 <karani.jaswanth@gmail.com> Co-authored-by: Yeoh, Hoong Tee <hoong.tee.yeoh@intel.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: chen, suyue <suyue.chen@intel.com>
This commit is contained in:
3
.github/workflows/scripts/build_push.sh
vendored
3
.github/workflows/scripts/build_push.sh
vendored
@@ -55,6 +55,9 @@ for MEGA_SVC in $1; do
|
|||||||
if [ "$MEGA_SVC" == "ChatQnA" ];then
|
if [ "$MEGA_SVC" == "ChatQnA" ];then
|
||||||
docker_build ${IMAGE_NAME}-conversation-ui docker/Dockerfile.react
|
docker_build ${IMAGE_NAME}-conversation-ui docker/Dockerfile.react
|
||||||
fi
|
fi
|
||||||
|
if [ "$MEGA_SVC" == "CodeGen" ];then
|
||||||
|
docker_build ${IMAGE_NAME}-react-ui docker/Dockerfile.react
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
"VisualQnA")
|
"VisualQnA")
|
||||||
echo "Not supported yet"
|
echo "Not supported yet"
|
||||||
|
|||||||
@@ -1,4 +1,8 @@
|
|||||||
FROM node as vite-app
|
# Copyright (C) 2024 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
# Use node 20.11.1 as the base image
|
||||||
|
FROM node:20.11.1 as vite-app
|
||||||
|
|
||||||
COPY . /usr/app
|
COPY . /usr/app
|
||||||
WORKDIR /usr/app/react
|
WORKDIR /usr/app/react
|
||||||
|
|||||||
BIN
CodeGen/assets/img/codegen_react.png
Normal file
BIN
CodeGen/assets/img/codegen_react.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 69 KiB |
@@ -38,11 +38,21 @@ cd GenAIExamples/CodeGen/docker/ui/
|
|||||||
docker build -t opea/codegen-ui:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f ./docker/Dockerfile .
|
docker build -t opea/codegen-ui:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f ./docker/Dockerfile .
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### 5. Build the React UI Docker Image
|
||||||
|
|
||||||
|
Construct the React frontend Docker image via the command below:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd GenAIExamples/CodeGen/docker/ui/
|
||||||
|
docker build -t opea/codegen-react-ui:latest --build-arg BACKEND_SERVICE_ENDPOINT=$BACKEND_SERVICE_ENDPOINT -f ./docker/Dockerfile.react .
|
||||||
|
```
|
||||||
|
|
||||||
Then run the command `docker images`, you will have the following 3 Docker images:
|
Then run the command `docker images`, you will have the following 3 Docker images:
|
||||||
|
|
||||||
- `opea/llm-tgi:latest`
|
- `opea/llm-tgi:latest`
|
||||||
- `opea/codegen:latest`
|
- `opea/codegen:latest`
|
||||||
- `opea/codegen-ui:latest`
|
- `opea/codegen-ui:latest`
|
||||||
|
- `opea/codegen-react-ui:latest`
|
||||||
|
|
||||||
## 🚀 Start MicroServices and MegaService
|
## 🚀 Start MicroServices and MegaService
|
||||||
|
|
||||||
@@ -143,12 +153,12 @@ export LANGCHAIN_TRACING_V2=true
|
|||||||
export LANGCHAIN_API_KEY=ls_...
|
export LANGCHAIN_API_KEY=ls_...
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 Launch the UI
|
## 🚀 Launch the Svelte Based UI
|
||||||
|
|
||||||
To access the frontend, open the following URL in your browser: `http://{host_ip}:5173`. By default, the UI runs on port 5173 internally. If you prefer to use a different host port to access the frontend, you can modify the port mapping in the `docker_compose.yaml` file as shown below:
|
To access the frontend, open the following URL in your browser: `http://{host_ip}:5173`. By default, the UI runs on port 5173 internally. If you prefer to use a different host port to access the frontend, you can modify the port mapping in the `docker_compose.yaml` file as shown below:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
codegen-xeon-ui-server:
|
codegen-gaudi-ui-server:
|
||||||
image: opea/codegen-ui:latest
|
image: opea/codegen-ui:latest
|
||||||
...
|
...
|
||||||
ports:
|
ports:
|
||||||
@@ -157,6 +167,20 @@ To access the frontend, open the following URL in your browser: `http://{host_ip
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## 🚀 Launch the React Based UI
|
||||||
|
|
||||||
|
To access the frontend, open the following URL in your browser: `http://{host_ip}:5174`. By default, the UI runs on port 5174 internally. If you prefer to use a different host port to access the frontend, you can modify the port mapping in the `docker_compose.yaml` file as shown below:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
codegen-gaudi-react-ui-server:
|
||||||
|
image: opea/codegen-react-ui:latest
|
||||||
|
...
|
||||||
|
ports:
|
||||||
|
- "80:5174"
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Install Copilot VSCode extension from Plugin Marketplace as the frontend
|
## Install Copilot VSCode extension from Plugin Marketplace as the frontend
|
||||||
|
|
||||||
In addition to the Svelte UI, users can also install the Copilot VSCode extension from the Plugin Marketplace as the frontend.
|
In addition to the Svelte UI, users can also install the Copilot VSCode extension from the Plugin Marketplace as the frontend.
|
||||||
|
|||||||
@@ -72,6 +72,19 @@ services:
|
|||||||
ipc: host
|
ipc: host
|
||||||
restart: always
|
restart: always
|
||||||
|
|
||||||
|
codegen-gaudi-react-ui-server:
|
||||||
|
image: opea/codegen-react-ui:latest
|
||||||
|
container_name: codegen-gaudi-react-ui-server
|
||||||
|
depends_on:
|
||||||
|
- codegen-gaudi-backend-server
|
||||||
|
ports:
|
||||||
|
- "5174:80"
|
||||||
|
build:
|
||||||
|
args:
|
||||||
|
- BACKEND_SERVICE_ENDPOINT=${BACKEND_SERVICE_ENDPOINT}
|
||||||
|
ipc: host
|
||||||
|
restart: always
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|||||||
24
CodeGen/docker/ui/docker/Dockerfile.react
Normal file
24
CodeGen/docker/ui/docker/Dockerfile.react
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Copyright (C) 2024 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
# Use node 20.11.1 as the base image
|
||||||
|
FROM node:20.11.1 as vite-app
|
||||||
|
|
||||||
|
COPY . /usr/app
|
||||||
|
WORKDIR /usr/app/react
|
||||||
|
|
||||||
|
ARG BACKEND_SERVICE_ENDPOINT
|
||||||
|
ENV VITE_CODE_GEN_URL=$BACKEND_SERVICE_ENDPOINT
|
||||||
|
|
||||||
|
RUN ["npm", "install"]
|
||||||
|
RUN ["npm", "run", "build"]
|
||||||
|
|
||||||
|
|
||||||
|
FROM nginx:alpine
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
|
||||||
|
COPY --from=vite-app /usr/app/react/nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
COPY --from=vite-app /usr/app/react/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
ENTRYPOINT ["nginx", "-g", "daemon off;"]
|
||||||
1
CodeGen/docker/ui/react/.env
Normal file
1
CodeGen/docker/ui/react/.env
Normal file
@@ -0,0 +1 @@
|
|||||||
|
VITE_CODE_GEN_URL=http://ip_address:7778/v1/codegen
|
||||||
11
CodeGen/docker/ui/react/.eslintrc.cjs
Normal file
11
CodeGen/docker/ui/react/.eslintrc.cjs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
env: { browser: true, es2020: true },
|
||||||
|
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react-hooks/recommended"],
|
||||||
|
ignorePatterns: ["dist", ".eslintrc.cjs"],
|
||||||
|
parser: "@typescript-eslint/parser",
|
||||||
|
plugins: ["react-refresh"],
|
||||||
|
rules: {
|
||||||
|
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
|
||||||
|
},
|
||||||
|
};
|
||||||
24
CodeGen/docker/ui/react/.gitignore
vendored
Normal file
24
CodeGen/docker/ui/react/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
.DS_Store
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
25
CodeGen/docker/ui/react/README.md
Normal file
25
CodeGen/docker/ui/react/README.md
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
<h1 align="center" id="title">Code Gen</h1>
|
||||||
|
|
||||||
|
### 📸 Project Screenshots
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<h2>🧐 Features</h2>
|
||||||
|
|
||||||
|
Here're some of the project's features:
|
||||||
|
|
||||||
|
- Generate code: generate the corresponding code based on the current user's input.
|
||||||
|
|
||||||
|
<h2>🛠️ Get it Running:</h2>
|
||||||
|
|
||||||
|
1. Clone the repo.
|
||||||
|
|
||||||
|
2. cd command to the current folder.
|
||||||
|
|
||||||
|
3. Modify the required .env variables.
|
||||||
|
```
|
||||||
|
VITE_CODE_GEN_URL = ''
|
||||||
|
```
|
||||||
|
4. Execute `npm install` to install the corresponding dependencies.
|
||||||
|
|
||||||
|
5. Execute `npm run dev` in both environments
|
||||||
18
CodeGen/docker/ui/react/index.html
Normal file
18
CodeGen/docker/ui/react/index.html
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<!--
|
||||||
|
Copyright (C) 2024 Intel Corporation
|
||||||
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<link rel="icon" type="image/svg+xml" href="/src/assets/opea-icon-color.svg" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Conversations UI</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="root"></div>
|
||||||
|
<script type="module" src="/src/main.tsx"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
20
CodeGen/docker/ui/react/nginx.conf
Normal file
20
CodeGen/docker/ui/react/nginx.conf
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
gzip on;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_comp_level 6;
|
||||||
|
gzip_buffers 16 8k;
|
||||||
|
gzip_http_version 1.1;
|
||||||
|
gzip_types font/woff2 text/css application/javascript application/json application/font-woff application/font-tff image/gif image/png image/svg+xml application/octet-stream;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
root /usr/share/nginx/html;
|
||||||
|
index index.html index.htm;
|
||||||
|
try_files $uri $uri/ /index.html =404;
|
||||||
|
|
||||||
|
location ~* \.(gif|jpe?g|png|webp|ico|svg|css|js|mp4|woff2)$ {
|
||||||
|
expires 1d;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
51
CodeGen/docker/ui/react/package.json
Normal file
51
CodeGen/docker/ui/react/package.json
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "ui",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.0.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "tsc && vite build",
|
||||||
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"test": "vitest"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mantine/core": "^7.10.0",
|
||||||
|
"@mantine/hooks": "^7.10.0",
|
||||||
|
"@mantine/notifications": "^7.10.2",
|
||||||
|
"@microsoft/fetch-event-source": "^2.0.1",
|
||||||
|
"@reduxjs/toolkit": "^2.2.5",
|
||||||
|
"@tabler/icons-react": "^3.5.0",
|
||||||
|
"axios": "^1.7.2",
|
||||||
|
"luxon": "^3.4.4",
|
||||||
|
"react": "^18.2.0",
|
||||||
|
"react-dom": "^18.2.0",
|
||||||
|
"react-markdown": "^9.0.1",
|
||||||
|
"react-syntax-highlighter": "^15.5.0",
|
||||||
|
"remark-frontmatter": "^5.0.0",
|
||||||
|
"remark-gfm": "^4.0.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@testing-library/react": "^16.0.0",
|
||||||
|
"@types/luxon": "^3.4.2",
|
||||||
|
"@types/node": "^20.12.12",
|
||||||
|
"@types/react": "^18.2.66",
|
||||||
|
"@types/react-dom": "^18.2.22",
|
||||||
|
"@types/react-syntax-highlighter": "^15.5.13",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^7.2.0",
|
||||||
|
"@typescript-eslint/parser": "^7.2.0",
|
||||||
|
"@vitejs/plugin-react": "^4.2.1",
|
||||||
|
"eslint": "^8.57.0",
|
||||||
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
|
"eslint-plugin-react-refresh": "^0.4.6",
|
||||||
|
"jsdom": "^24.1.0",
|
||||||
|
"postcss": "^8.4.38",
|
||||||
|
"postcss-preset-mantine": "^1.15.0",
|
||||||
|
"postcss-simple-vars": "^7.0.1",
|
||||||
|
"sass": "1.64.2",
|
||||||
|
"typescript": "^5.2.2",
|
||||||
|
"vite": "^5.2.13",
|
||||||
|
"vitest": "^1.6.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
14
CodeGen/docker/ui/react/postcss.config.cjs
Normal file
14
CodeGen/docker/ui/react/postcss.config.cjs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
module.exports = {
|
||||||
|
plugins: {
|
||||||
|
"postcss-preset-mantine": {},
|
||||||
|
"postcss-simple-vars": {
|
||||||
|
variables: {
|
||||||
|
"mantine-breakpoint-xs": "36em",
|
||||||
|
"mantine-breakpoint-sm": "48em",
|
||||||
|
"mantine-breakpoint-md": "62em",
|
||||||
|
"mantine-breakpoint-lg": "75em",
|
||||||
|
"mantine-breakpoint-xl": "88em",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
42
CodeGen/docker/ui/react/src/App.scss
Normal file
42
CodeGen/docker/ui/react/src/App.scss
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
@import "./styles/styles";
|
||||||
|
|
||||||
|
.root {
|
||||||
|
@include flex(row, nowrap, flex-start, flex-start);
|
||||||
|
}
|
||||||
|
|
||||||
|
.layout-wrapper {
|
||||||
|
@include absolutes;
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
|
grid-template-columns: 80px auto;
|
||||||
|
grid-template-rows: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Scrollbar CSS ===== */
|
||||||
|
/* Firefox */
|
||||||
|
* {
|
||||||
|
scrollbar-width: thin;
|
||||||
|
scrollbar-color: #d6d6d6 #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Chrome, Edge, and Safari */
|
||||||
|
*::-webkit-scrollbar {
|
||||||
|
width: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-track {
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
*::-webkit-scrollbar-thumb {
|
||||||
|
background-color: #d6d6d6;
|
||||||
|
border-radius: 16px;
|
||||||
|
border: 4px double #dedede;
|
||||||
|
}
|
||||||
32
CodeGen/docker/ui/react/src/App.tsx
Normal file
32
CodeGen/docker/ui/react/src/App.tsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import "./App.scss"
|
||||||
|
import { MantineProvider } from "@mantine/core"
|
||||||
|
import '@mantine/notifications/styles.css';
|
||||||
|
import { SideNavbar, SidebarNavList } from "./components/sidebar/sidebar"
|
||||||
|
import { IconMessages } from "@tabler/icons-react"
|
||||||
|
import { Notifications } from '@mantine/notifications';
|
||||||
|
import CodeGen from "./components/CodeGen/CodeGen";
|
||||||
|
|
||||||
|
const title = "Code Gen"
|
||||||
|
const navList: SidebarNavList = [
|
||||||
|
{ icon: IconMessages, label: title }
|
||||||
|
]
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
|
||||||
|
return (
|
||||||
|
<MantineProvider>
|
||||||
|
<Notifications position="top-right" />
|
||||||
|
<div className="layout-wrapper">
|
||||||
|
<SideNavbar navList={navList} />
|
||||||
|
<div className="content">
|
||||||
|
<CodeGen />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</MantineProvider>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default App
|
||||||
14
CodeGen/docker/ui/react/src/__tests__/util.test.ts
Normal file
14
CodeGen/docker/ui/react/src/__tests__/util.test.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { describe, expect, test } from "vitest";
|
||||||
|
import { getCurrentTimeStamp, uuidv4 } from "../common/util";
|
||||||
|
|
||||||
|
describe("unit tests", () => {
|
||||||
|
test("check UUID is of length 36", () => {
|
||||||
|
expect(uuidv4()).toHaveLength(36);
|
||||||
|
});
|
||||||
|
test("check TimeStamp generated is of unix", () => {
|
||||||
|
expect(getCurrentTimeStamp()).toBe(Math.floor(Date.now() / 1000));
|
||||||
|
});
|
||||||
|
});
|
||||||
39
CodeGen/docker/ui/react/src/assets/opea-icon-black.svg
Normal file
39
CodeGen/docker/ui/react/src/assets/opea-icon-black.svg
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 28.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="800px" height="800px" viewBox="0 0 800 800" style="enable-background:new 0 0 800 800;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.Drop_x0020_Shadow{fill:none;}
|
||||||
|
.Outer_x0020_Glow_x0020_5_x0020_pt{fill:none;}
|
||||||
|
.Blue_x0020_Neon{fill:none;stroke:#8AACDA;stroke-width:7;stroke-linecap:round;stroke-linejoin:round;}
|
||||||
|
.Chrome_x0020_Highlight{fill:url(#SVGID_1_);stroke:#FFFFFF;stroke-width:0.3629;stroke-miterlimit:1;}
|
||||||
|
.Jive_GS{fill:#FFDD00;}
|
||||||
|
.Alyssa_GS{fill:#A6D0E4;}
|
||||||
|
.st0{fill:#FF6900;}
|
||||||
|
.st1{fill:#FFB500;}
|
||||||
|
.st2{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-1640" y1="-1640" x2="-1640" y2="-1641">
|
||||||
|
<stop offset="0" style="stop-color:#656565"/>
|
||||||
|
<stop offset="0.618" style="stop-color:#1B1B1B"/>
|
||||||
|
<stop offset="0.6292" style="stop-color:#545454"/>
|
||||||
|
<stop offset="0.9831" style="stop-color:#3E3E3E"/>
|
||||||
|
</linearGradient>
|
||||||
|
<g>
|
||||||
|
<polygon points="400,0 737.5,181.7 607.3,252.8 269.7,71.1 "/>
|
||||||
|
<path d="M708.3,414.7l29.2,15.7l-130.3,71.1l-44.9-24.2v-31.7l40,21.5c1.5,0.8,3.2,1.2,4.9,1.2c1.7,0,3.4-0.4,5-1.3l0,0
|
||||||
|
L708.3,414.7z"/>
|
||||||
|
<path d="M557.3,532.1c-0.1-0.1-0.3-0.1-0.4-0.2l0,0l-34.2-18.4l31.2-17l42.9,23.1v169.9l-34.5-18.6V541
|
||||||
|
C562.4,537.3,560.4,533.9,557.3,532.1z"/>
|
||||||
|
<polygon points="410.4,381.3 541.6,309.7 541.6,479.5 410.4,551.2 "/>
|
||||||
|
<path d="M258.4,88.5l338.6,182.3v169.9l-34.5-18.6V292.2c0-3.7-1.9-7-5.1-8.9c-0.1-0.1-0.3-0.1-0.4-0.2l0,0L258.4,122.3V88.5z"/>
|
||||||
|
<polygon points="192.7,110.6 530.3,292.3 400,363.4 62.5,181.6 "/>
|
||||||
|
<polygon points="51.1,369 51.1,199 389.6,381.3 389.6,551.3 96.6,393.5 "/>
|
||||||
|
<path d="M91.7,414.4l303.4,163.3c1.5,0.8,3.2,1.2,4.9,1.2c1.7,0,3.4-0.4,5-1.3l0,0l96.1-52.4l29.2,15.7L400,612.1L62.5,430.4
|
||||||
|
L91.7,414.4z"/>
|
||||||
|
<polygon points="51.1,447.8 389.6,630.1 389.6,800 51.1,617.7 "/>
|
||||||
|
<polygon points="541.6,728.3 410.4,799.9 410.4,630 541.6,558.4 "/>
|
||||||
|
<polygon points="748.9,617.7 617.6,689.3 617.6,519.5 748.9,447.9 "/>
|
||||||
|
<polygon points="748.9,369 617.6,440.6 617.6,270.7 748.9,199.1 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.2 KiB |
40
CodeGen/docker/ui/react/src/assets/opea-icon-color.svg
Normal file
40
CodeGen/docker/ui/react/src/assets/opea-icon-color.svg
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 28.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||||
|
width="800px" height="800px" viewBox="0 0 800 800" style="enable-background:new 0 0 800 800;" xml:space="preserve">
|
||||||
|
<style type="text/css">
|
||||||
|
.Drop_x0020_Shadow{fill:none;}
|
||||||
|
.Outer_x0020_Glow_x0020_5_x0020_pt{fill:none;}
|
||||||
|
.Blue_x0020_Neon{fill:none;stroke:#8AACDA;stroke-width:7;stroke-linecap:round;stroke-linejoin:round;}
|
||||||
|
.Chrome_x0020_Highlight{fill:url(#SVGID_1_);stroke:#FFFFFF;stroke-width:0.3629;stroke-miterlimit:1;}
|
||||||
|
.Jive_GS{fill:#FFDD00;}
|
||||||
|
.Alyssa_GS{fill:#A6D0E4;}
|
||||||
|
.st0{fill:#FF6900;}
|
||||||
|
.st1{fill:#FFB500;}
|
||||||
|
.st2{fill:#FFFFFF;}
|
||||||
|
</style>
|
||||||
|
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="-820" y1="-1640" x2="-820" y2="-1641">
|
||||||
|
<stop offset="0" style="stop-color:#656565"/>
|
||||||
|
<stop offset="0.618" style="stop-color:#1B1B1B"/>
|
||||||
|
<stop offset="0.6292" style="stop-color:#545454"/>
|
||||||
|
<stop offset="0.9831" style="stop-color:#3E3E3E"/>
|
||||||
|
</linearGradient>
|
||||||
|
<g>
|
||||||
|
<polygon class="st0" points="400,0 737.5,181.7 607.3,252.8 269.7,71.1 "/>
|
||||||
|
<path class="st1" d="M708.3,414.7l29.2,15.7l-130.3,71.1l-44.9-24.2v-31.7l40,21.5c1.5,0.8,3.2,1.2,4.9,1.2c1.7,0,3.4-0.4,5-1.3
|
||||||
|
l0,0L708.3,414.7z"/>
|
||||||
|
<path class="st1" d="M557.3,532.1c-0.1-0.1-0.3-0.1-0.4-0.2l0,0l-34.2-18.4l31.2-17l42.9,23.1v169.9l-34.5-18.6V541
|
||||||
|
C562.4,537.3,560.4,533.9,557.3,532.1z"/>
|
||||||
|
<polygon class="st1" points="410.4,381.3 541.6,309.7 541.6,479.5 410.4,551.2 "/>
|
||||||
|
<path class="st0" d="M258.4,88.5l338.6,182.3v169.9l-34.5-18.6V292.2c0-3.7-1.9-7-5.1-8.9c-0.1-0.1-0.3-0.1-0.4-0.2l0,0
|
||||||
|
L258.4,122.3V88.5z"/>
|
||||||
|
<polygon class="st1" points="192.7,110.6 530.3,292.3 400,363.4 62.5,181.6 "/>
|
||||||
|
<polygon class="st1" points="51.1,369 51.1,199 389.6,381.3 389.6,551.3 96.6,393.5 "/>
|
||||||
|
<path class="st0" d="M91.7,414.4l303.4,163.3c1.5,0.8,3.2,1.2,4.9,1.2c1.7,0,3.4-0.4,5-1.3l0,0l96.1-52.4l29.2,15.7L400,612.1
|
||||||
|
L62.5,430.4L91.7,414.4z"/>
|
||||||
|
<polygon class="st0" points="51.1,447.8 389.6,630.1 389.6,800 51.1,617.7 "/>
|
||||||
|
<polygon class="st0" points="541.6,728.3 410.4,799.9 410.4,630 541.6,558.4 "/>
|
||||||
|
<polygon class="st1" points="748.9,617.7 617.6,689.3 617.6,519.5 748.9,447.9 "/>
|
||||||
|
<polygon class="st0" points="748.9,369 617.6,440.6 617.6,270.7 748.9,199.1 "/>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 2.4 KiB |
8
CodeGen/docker/ui/react/src/common/client.ts
Normal file
8
CodeGen/docker/ui/react/src/common/client.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
//add iterceptors to add any request headers
|
||||||
|
|
||||||
|
export default axios;
|
||||||
12
CodeGen/docker/ui/react/src/common/util.ts
Normal file
12
CodeGen/docker/ui/react/src/common/util.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
export const getCurrentTimeStamp = () => {
|
||||||
|
return Math.floor(Date.now() / 1000);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const uuidv4 = () => {
|
||||||
|
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) =>
|
||||||
|
(+c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (+c / 4)))).toString(16),
|
||||||
|
);
|
||||||
|
};
|
||||||
135
CodeGen/docker/ui/react/src/components/CodeGen/CodeGen.tsx
Normal file
135
CodeGen/docker/ui/react/src/components/CodeGen/CodeGen.tsx
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { KeyboardEventHandler, SyntheticEvent, useEffect, useRef, useState } from 'react'
|
||||||
|
import styleClasses from "./codeGen.module.scss"
|
||||||
|
import { ActionIcon, Textarea, Title, rem } from '@mantine/core'
|
||||||
|
import { IconArrowRight } from '@tabler/icons-react'
|
||||||
|
import { ConversationMessage } from '../Message/conversationMessage'
|
||||||
|
import { fetchEventSource } from '@microsoft/fetch-event-source'
|
||||||
|
import { CODE_GEN_URL } from '../../config'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const CodeGen = () => {
|
||||||
|
const [prompt, setPrompt] = useState<string>("")
|
||||||
|
const [submittedPrompt, setSubmittedPrompt] = useState<string>("")
|
||||||
|
const [response,setResponse] = useState<string>("");
|
||||||
|
const promptInputRef = useRef<HTMLTextAreaElement>(null)
|
||||||
|
const scrollViewport = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
|
const toSend = "Enter"
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
setResponse("")
|
||||||
|
setSubmittedPrompt(prompt)
|
||||||
|
const body = {
|
||||||
|
messages:prompt
|
||||||
|
}
|
||||||
|
fetchEventSource(CODE_GEN_URL, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept":"*/*"
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
openWhenHidden: true,
|
||||||
|
async onopen(response) {
|
||||||
|
if (response.ok) {
|
||||||
|
return;
|
||||||
|
} else if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
||||||
|
const e = await response.json();
|
||||||
|
console.log(e);
|
||||||
|
throw Error(e.error.message);
|
||||||
|
} else {
|
||||||
|
console.log("error", response);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onmessage(msg) {
|
||||||
|
if (msg?.data != "[DONE]") {
|
||||||
|
try {
|
||||||
|
const match = msg.data.match(/b'([^']*)'/);
|
||||||
|
if (match && match[1] != "</s>") {
|
||||||
|
const extractedText = match[1].replace(/\\n/g, "\n");
|
||||||
|
setResponse(prev=>prev+extractedText);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.log("something wrong in msg", e);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onerror(err) {
|
||||||
|
console.log("error", err);
|
||||||
|
setResponse("")
|
||||||
|
throw err;
|
||||||
|
},
|
||||||
|
onclose() {
|
||||||
|
setPrompt("")
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const scrollToBottom = () => {
|
||||||
|
scrollViewport.current!.scrollTo({ top: scrollViewport.current!.scrollHeight })
|
||||||
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
scrollToBottom()
|
||||||
|
}, [response])
|
||||||
|
|
||||||
|
const handleKeyDown: KeyboardEventHandler = (event) => {
|
||||||
|
if (!event.shiftKey && event.key === toSend) {
|
||||||
|
handleSubmit()
|
||||||
|
setTimeout(() => {
|
||||||
|
setPrompt("")
|
||||||
|
}, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = (event: SyntheticEvent) => {
|
||||||
|
event.preventDefault()
|
||||||
|
setPrompt((event.target as HTMLTextAreaElement).value)
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className={styleClasses.codeGenWrapper}>
|
||||||
|
<div className={styleClasses.codeGenContent}>
|
||||||
|
<div className={styleClasses.codeGenContentMessages}>
|
||||||
|
<div className={styleClasses.codeGenTitle}>
|
||||||
|
<Title order={3}>CodeGen</Title>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styleClasses.historyContainer} ref={scrollViewport}>
|
||||||
|
{submittedPrompt && (
|
||||||
|
<ConversationMessage key={`_ai`} date={Date.now()} human={true} message={submittedPrompt} />
|
||||||
|
)}
|
||||||
|
{response && (
|
||||||
|
<ConversationMessage key={`_ai`} date={Date.now()} human={false} message={response} />
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={styleClasses.codeGenActions}>
|
||||||
|
<Textarea
|
||||||
|
radius="xl"
|
||||||
|
size="md"
|
||||||
|
placeholder="Ask a question"
|
||||||
|
ref={promptInputRef}
|
||||||
|
onKeyDown={handleKeyDown}
|
||||||
|
onChange={handleChange}
|
||||||
|
value={prompt}
|
||||||
|
rightSectionWidth={42}
|
||||||
|
rightSection={
|
||||||
|
<ActionIcon onClick={handleSubmit} size={32} radius="xl" variant="filled">
|
||||||
|
<IconArrowRight style={{ width: rem(18), height: rem(18) }} stroke={1.5} />
|
||||||
|
</ActionIcon>
|
||||||
|
}
|
||||||
|
// {...props}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
)
|
||||||
|
}
|
||||||
|
export default CodeGen;
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
@import "../../styles/styles";
|
||||||
|
|
||||||
|
.spacer {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeGenWrapper {
|
||||||
|
@include flex(row, nowrap, flex-start, flex-start);
|
||||||
|
flex: 1 1 auto;
|
||||||
|
height: 100%;
|
||||||
|
& > * {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.codeGenContent {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
position: relative;
|
||||||
|
.codeGenContentMessages {
|
||||||
|
@include absolutes;
|
||||||
|
// @include flex(column, nowrap, flex-start, flex-start);
|
||||||
|
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas:
|
||||||
|
"header"
|
||||||
|
"messages"
|
||||||
|
"inputs";
|
||||||
|
|
||||||
|
grid-template-columns: auto;
|
||||||
|
grid-template-rows: 60px auto 100px;
|
||||||
|
|
||||||
|
.codeGenTitle {
|
||||||
|
grid-area: header;
|
||||||
|
@include flex(row, nowrap, center, flex-start);
|
||||||
|
height: 60px;
|
||||||
|
padding: 8px 24px;
|
||||||
|
border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
|
||||||
|
}
|
||||||
|
|
||||||
|
.historyContainer {
|
||||||
|
grid-area: messages;
|
||||||
|
overflow: auto;
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px 32px;
|
||||||
|
& > * {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.codeGenActions {
|
||||||
|
// padding: --var()
|
||||||
|
grid-area: inputs;
|
||||||
|
padding: 18px;
|
||||||
|
border-top: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
@import "../../styles/styles";
|
||||||
|
|
||||||
|
.conversationMessage {
|
||||||
|
@include flex(column, nowrap, flex-start, flex-start);
|
||||||
|
margin-top: 16px;
|
||||||
|
padding: 0 32px;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { IconAi, IconUser } from "@tabler/icons-react"
|
||||||
|
import style from "./conversationMessage.module.scss"
|
||||||
|
import { Group, Text } from "@mantine/core"
|
||||||
|
import { DateTime } from "luxon"
|
||||||
|
import Markdown from "../Shared/Markdown/Markdown"
|
||||||
|
|
||||||
|
export interface ConversationMessageProps {
|
||||||
|
message: string
|
||||||
|
human: boolean
|
||||||
|
date: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export function ConversationMessage({ human, message, date }: ConversationMessageProps) {
|
||||||
|
const dateFormat = () => {
|
||||||
|
return DateTime.fromJSDate(new Date(date)).toLocaleString(DateTime.DATETIME_MED)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className={style.conversationMessage}>
|
||||||
|
<Group>
|
||||||
|
{human && <IconUser />}
|
||||||
|
{!human && <IconAi />}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<Text size="sm">
|
||||||
|
{human && "You"} {!human && "Assistant"}
|
||||||
|
</Text>
|
||||||
|
<Text size="xs" c="dimmed">
|
||||||
|
{dateFormat()}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
</Group>
|
||||||
|
<Text pl={54} pt="sm" size="sm">
|
||||||
|
{human? message : (<Markdown content={message}/>)}
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import styles from './codeRender.module.scss'
|
||||||
|
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
|
||||||
|
import { tomorrow } from "react-syntax-highlighter/dist/esm/styles/prism";
|
||||||
|
import { IconCopy } from '@tabler/icons-react';
|
||||||
|
import { Button, CopyButton } from '@mantine/core';
|
||||||
|
|
||||||
|
type CodeRenderProps = {
|
||||||
|
cleanCode: React.ReactNode,
|
||||||
|
language: string,
|
||||||
|
inline: boolean
|
||||||
|
}
|
||||||
|
const CodeRender = ({ cleanCode, language, inline }:CodeRenderProps) => {
|
||||||
|
cleanCode = String(cleanCode).replace(/\n$/, '').replace(/^\s*[\r\n]/gm, '') //right trim and remove empty lines from the input
|
||||||
|
console.log(styles)
|
||||||
|
try {
|
||||||
|
return inline ? (<code className='inline-code'><i>{cleanCode}</i></code>) : (
|
||||||
|
<div className={styles.code}>
|
||||||
|
<div className={styles.codeHead}>
|
||||||
|
<div className='code-title'>
|
||||||
|
{language || "language not detected"}
|
||||||
|
</div>
|
||||||
|
<div className={styles.codeActionGroup} >
|
||||||
|
<CopyButton value={cleanCode.toString()}>
|
||||||
|
{({ copied, copy }) => (
|
||||||
|
<Button color={copied ? 'teal' : 'blue'} styles={{root:{border:"none"}}} leftSection={<IconCopy size={12} />} onClick={copy}>
|
||||||
|
{copied ? 'Copied' : 'Copy'}
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</CopyButton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<SyntaxHighlighter
|
||||||
|
className={styles.codeHighlighterDiv}
|
||||||
|
children={cleanCode.toString()}
|
||||||
|
wrapLongLines={true}
|
||||||
|
style={tomorrow}
|
||||||
|
language={language}
|
||||||
|
PreTag="div"
|
||||||
|
/>
|
||||||
|
</div>)
|
||||||
|
} catch (err) {
|
||||||
|
return (
|
||||||
|
<pre>
|
||||||
|
{cleanCode}
|
||||||
|
</pre>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default CodeRender;
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
@import "../../../styles/styles";
|
||||||
|
|
||||||
|
.code {
|
||||||
|
margin: 7px 0px;
|
||||||
|
.codeHead {
|
||||||
|
background: #379af1;
|
||||||
|
|
||||||
|
padding: 0px 10px !important;
|
||||||
|
@include flex(row, nowrap, center, space-between);
|
||||||
|
.codeTitle {
|
||||||
|
}
|
||||||
|
.codeActionGroup {
|
||||||
|
@include flex(row, nowrap, center, flex-start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.codeHighlighterDiv {
|
||||||
|
margin: 0px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.inlineCode {
|
||||||
|
background: #d7d7d7;
|
||||||
|
}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import markdownStyles from './markdown.module.scss'
|
||||||
|
import ReactMarkdown from 'react-markdown';
|
||||||
|
import remarkGfm from 'remark-gfm';
|
||||||
|
import remarkFrontmatter from 'remark-frontmatter';
|
||||||
|
// import Mermaid from '../../shared/Mermaid/Mermaid';
|
||||||
|
import CodeRender from '../CodeRender/CodeRender';
|
||||||
|
|
||||||
|
type MarkdownProps = {
|
||||||
|
content: string
|
||||||
|
}
|
||||||
|
const Markdown = ({ content }: MarkdownProps) => {
|
||||||
|
return (
|
||||||
|
<ReactMarkdown
|
||||||
|
children={content}
|
||||||
|
className={markdownStyles.md}
|
||||||
|
remarkPlugins={[remarkGfm, remarkFrontmatter]}
|
||||||
|
components={{
|
||||||
|
p: ({ children, ...props }) => {
|
||||||
|
return (
|
||||||
|
<p {...props} style={{ whiteSpace: "pre-wrap" }}>
|
||||||
|
{children}
|
||||||
|
</p>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
a: ({ children, ...props }) => {
|
||||||
|
return (
|
||||||
|
<a
|
||||||
|
href={props.href}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
table: ({ children, ...props }) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={markdownStyles.tableDiv}
|
||||||
|
style={{
|
||||||
|
overflowX: "auto",
|
||||||
|
padding: "10px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<table {...props}>{children}</table>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
//@ts-expect-error inline can undefined sometimes
|
||||||
|
code({ inline, className, children, }) {
|
||||||
|
const lang = /language-(\w+)/.exec(className || '')
|
||||||
|
// if (lang && lang[1] === "mermaid") {
|
||||||
|
// return <Mermaid content={String(children).replace(/\n$/, '')} key={"id"} />
|
||||||
|
// }
|
||||||
|
return <CodeRender cleanCode={children} inline={inline} language={(lang && lang[1]) || ""} />
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Markdown;
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
.tableDiv {
|
||||||
|
table,
|
||||||
|
th,
|
||||||
|
td {
|
||||||
|
border: 1px solid black;
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.md {
|
||||||
|
li {
|
||||||
|
margin-left: 35px; /* Adjust the value based on your preference */
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
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 "../../styles/styles";
|
||||||
|
|
||||||
|
.navbar {
|
||||||
|
width: 100%;
|
||||||
|
@include flex(column, nowrap, center, flex-start);
|
||||||
|
padding: var(--mantine-spacing-md);
|
||||||
|
background-color: var(--mantine-color-blue-filled);
|
||||||
|
// background-color: light-dark(var(--mantine-color-white), var(--mantine-color-dark-6));
|
||||||
|
// border-right: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbarMain {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbarLogo {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
padding-top: var(--mantine-spacing-md);
|
||||||
|
margin-bottom: var(--mantine-spacing-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
.link {
|
||||||
|
width: 44px;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: var(--mantine-radius-md);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--mantine-color-blue-7);
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-active] {
|
||||||
|
&,
|
||||||
|
&:hover {
|
||||||
|
box-shadow: var(--mantine-shadow-sm);
|
||||||
|
background-color: var(--mantine-color-white);
|
||||||
|
color: var(--mantine-color-blue-6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.aside {
|
||||||
|
flex: 0 0 60px;
|
||||||
|
background-color: var(--mantine-color-body);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
border-right: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-7));
|
||||||
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
height: 60px;
|
||||||
|
padding-top: var(--mantine-spacing-s);
|
||||||
|
border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-7));
|
||||||
|
margin-bottom: var(--mantine-spacing-xl);
|
||||||
|
}
|
||||||
|
.logoImg {
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
58
CodeGen/docker/ui/react/src/components/sidebar/sidebar.tsx
Normal file
58
CodeGen/docker/ui/react/src/components/sidebar/sidebar.tsx
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { useState } from "react"
|
||||||
|
import { Tooltip, UnstyledButton, Stack, rem } from "@mantine/core"
|
||||||
|
import { IconHome2 } from "@tabler/icons-react"
|
||||||
|
import classes from "./sidebar.module.scss"
|
||||||
|
import OpeaLogo from "../../assets/opea-icon-color.svg"
|
||||||
|
interface NavbarLinkProps {
|
||||||
|
icon: typeof IconHome2
|
||||||
|
label: string
|
||||||
|
active?: boolean
|
||||||
|
onClick?(): void
|
||||||
|
}
|
||||||
|
|
||||||
|
function NavbarLink({ icon: Icon, label, active, onClick }: NavbarLinkProps) {
|
||||||
|
return (
|
||||||
|
<Tooltip label={label} position="right" transitionProps={{ duration: 0 }}>
|
||||||
|
<UnstyledButton onClick={onClick} className={classes.link} data-active={active || undefined}>
|
||||||
|
<Icon style={{ width: rem(20), height: rem(20) }} stroke={1.5} />
|
||||||
|
</UnstyledButton>
|
||||||
|
</Tooltip>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SidebarNavItem {
|
||||||
|
icon: typeof IconHome2
|
||||||
|
label: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type SidebarNavList = SidebarNavItem[]
|
||||||
|
|
||||||
|
export interface SideNavbarProps {
|
||||||
|
navList: SidebarNavList
|
||||||
|
}
|
||||||
|
|
||||||
|
export function SideNavbar({ navList }: SideNavbarProps) {
|
||||||
|
const [active, setActive] = useState(0)
|
||||||
|
|
||||||
|
|
||||||
|
const links = navList.map((link, index) => (
|
||||||
|
<NavbarLink {...link} key={link.label} active={index === active} onClick={() => setActive(index)} />
|
||||||
|
))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<nav className={classes.navbar}>
|
||||||
|
<div className={classes.navbarLogo}>
|
||||||
|
<img className={classes.logoImg} src={OpeaLogo} alt="opea logo" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className={classes.navbarMain}>
|
||||||
|
<Stack justify="center" gap={0}>
|
||||||
|
{links}
|
||||||
|
</Stack>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
)
|
||||||
|
}
|
||||||
4
CodeGen/docker/ui/react/src/config.ts
Normal file
4
CodeGen/docker/ui/react/src/config.ts
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
export const CODE_GEN_URL = import.meta.env.VITE_CODE_GEN_URL;
|
||||||
20
CodeGen/docker/ui/react/src/index.scss
Normal file
20
CodeGen/docker/ui/react/src/index.scss
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
@import "@mantine/core/styles.css";
|
||||||
|
|
||||||
|
:root {
|
||||||
|
font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
13
CodeGen/docker/ui/react/src/main.tsx
Normal file
13
CodeGen/docker/ui/react/src/main.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import React from "react"
|
||||||
|
import ReactDOM from "react-dom/client"
|
||||||
|
import App from "./App.tsx"
|
||||||
|
import "./index.scss"
|
||||||
|
|
||||||
|
ReactDOM.createRoot(document.getElementById("root")!).render(
|
||||||
|
<React.StrictMode>
|
||||||
|
<App />
|
||||||
|
</React.StrictMode>
|
||||||
|
)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
@import "../layout/flex";
|
||||||
|
|
||||||
|
@mixin sidebar {
|
||||||
|
@include flex(column, nowrap, flex-start, flex-start);
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
@mixin textWrapEllipsis {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
@import "../layout/flex";
|
||||||
|
@import "../components/content.scss";
|
||||||
|
|
||||||
|
.contextWrapper {
|
||||||
|
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
|
||||||
|
border-right: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
|
||||||
|
width: 180px;
|
||||||
|
overflow-y: hidden;
|
||||||
|
overflow-x: hidden;
|
||||||
|
// overflow-y: auto;
|
||||||
|
.contextTitle {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
font-family:
|
||||||
|
Greycliff CF,
|
||||||
|
var(--mantine-font-family);
|
||||||
|
margin-bottom: var(--mantine-spacing-xl);
|
||||||
|
background-color: var(--mantine-color-body);
|
||||||
|
padding: var(--mantine-spacing-md);
|
||||||
|
padding-top: 18px;
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-7));
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextList {
|
||||||
|
height: 70vh;
|
||||||
|
// display: flex();
|
||||||
|
|
||||||
|
.contextListItem {
|
||||||
|
display: block;
|
||||||
|
text-decoration: none;
|
||||||
|
border-top-right-radius: var(--mantine-radius-md);
|
||||||
|
border-bottom-right-radius: var(--mantine-radius-md);
|
||||||
|
color: light-dark(var(--mantine-color-gray-7), var(--mantine-color-dark-0));
|
||||||
|
padding: 0 var(--mantine-spacing-md);
|
||||||
|
font-size: var(--mantine-font-size-sm);
|
||||||
|
margin-right: var(--mantine-spacing-md);
|
||||||
|
font-weight: 500;
|
||||||
|
height: 44px;
|
||||||
|
width: 100%;
|
||||||
|
line-height: 44px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.contextItemName {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
width: 130px;
|
||||||
|
@include textWrapEllipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5));
|
||||||
|
color: light-dark(var(--mantine-color-dark), var(--mantine-color-light));
|
||||||
|
}
|
||||||
|
|
||||||
|
&[data-active] {
|
||||||
|
&,
|
||||||
|
&:hover {
|
||||||
|
border-left-color: var(--mantine-color-blue-filled);
|
||||||
|
background-color: var(--mantine-color-blue-filled);
|
||||||
|
color: var(--mantine-color-white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
CodeGen/docker/ui/react/src/styles/layout/_basics.scss
Normal file
7
CodeGen/docker/ui/react/src/styles/layout/_basics.scss
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@mixin absolutes {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
6
CodeGen/docker/ui/react/src/styles/layout/_flex.scss
Normal file
6
CodeGen/docker/ui/react/src/styles/layout/_flex.scss
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@mixin flex($direction: row, $wrap: nowrap, $alignItems: center, $justifyContent: center) {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: $direction $wrap;
|
||||||
|
align-items: $alignItems;
|
||||||
|
justify-content: $justifyContent;
|
||||||
|
}
|
||||||
5
CodeGen/docker/ui/react/src/styles/styles.scss
Normal file
5
CodeGen/docker/ui/react/src/styles/styles.scss
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
@import "layout/flex";
|
||||||
|
@import "layout/basics";
|
||||||
4
CodeGen/docker/ui/react/src/vite-env.d.ts
vendored
Normal file
4
CodeGen/docker/ui/react/src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
/// <reference types="vite/client" />
|
||||||
23
CodeGen/docker/ui/react/tsconfig.json
Normal file
23
CodeGen/docker/ui/react/tsconfig.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||||
|
"module": "ESNext",
|
||||||
|
"skipLibCheck": true,
|
||||||
|
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowImportingTsExtensions": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"jsx": "react-jsx",
|
||||||
|
|
||||||
|
"strict": true,
|
||||||
|
"noUnusedLocals": true,
|
||||||
|
"noUnusedParameters": true,
|
||||||
|
"noFallthroughCasesInSwitch": true
|
||||||
|
},
|
||||||
|
"include": ["src"],
|
||||||
|
"references": [{ "path": "./tsconfig.node.json" }]
|
||||||
|
}
|
||||||
11
CodeGen/docker/ui/react/tsconfig.node.json
Normal file
11
CodeGen/docker/ui/react/tsconfig.node.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"composite": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "bundler",
|
||||||
|
"allowSyntheticDefaultImports": true,
|
||||||
|
"strict": true
|
||||||
|
},
|
||||||
|
"include": ["vite.config.ts"]
|
||||||
|
}
|
||||||
27
CodeGen/docker/ui/react/vite.config.ts
Normal file
27
CodeGen/docker/ui/react/vite.config.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
// Copyright (C) 2024 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { defineConfig } from "vitest/config";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
css: {
|
||||||
|
preprocessorOptions: {
|
||||||
|
scss: {
|
||||||
|
additionalData: `@import "./src/styles/styles.scss";`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [react()],
|
||||||
|
server: {
|
||||||
|
port: 3000,
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
globals: true,
|
||||||
|
environment: "jsdom",
|
||||||
|
},
|
||||||
|
define: {
|
||||||
|
"import.meta.env": process.env,
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -174,6 +174,20 @@ Here is an example of running CodeGen in the UI:
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
## 🚀 Launch the React Based UI
|
||||||
|
|
||||||
|
To access the frontend, open the following URL in your browser: `http://{host_ip}:5174`. By default, the UI runs on port 5174 internally. If you prefer to use a different host port to access the frontend, you can modify the port mapping in the `docker_compose.yaml` file as shown below:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
codegen-xeon-react-ui-server:
|
||||||
|
image: opea/codegen-react-ui:latest
|
||||||
|
...
|
||||||
|
ports:
|
||||||
|
- "80:5174"
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Install Copilot VSCode extension from Plugin Marketplace as the frontend
|
## Install Copilot VSCode extension from Plugin Marketplace as the frontend
|
||||||
|
|
||||||
In addition to the Svelte UI, users can also install the Copilot VSCode extension from the Plugin Marketplace as the frontend.
|
In addition to the Svelte UI, users can also install the Copilot VSCode extension from the Plugin Marketplace as the frontend.
|
||||||
|
|||||||
@@ -66,6 +66,18 @@ services:
|
|||||||
- BASIC_URL=${BACKEND_SERVICE_ENDPOINT}
|
- BASIC_URL=${BACKEND_SERVICE_ENDPOINT}
|
||||||
ipc: host
|
ipc: host
|
||||||
restart: always
|
restart: always
|
||||||
|
codegen-xeon-react-ui-server:
|
||||||
|
image: opea/codegen-react-ui:latest
|
||||||
|
container_name: codegen-xeon-react-ui-server
|
||||||
|
depends_on:
|
||||||
|
- codegen-xeon-backend-server
|
||||||
|
ports:
|
||||||
|
- "5174:80"
|
||||||
|
build:
|
||||||
|
args:
|
||||||
|
- BACKEND_SERVICE_ENDPOINT=${BACKEND_SERVICE_ENDPOINT}
|
||||||
|
ipc: host
|
||||||
|
restart: always
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
default:
|
default:
|
||||||
|
|||||||
36
CodeGen/kubernetes/manifests/xeon/ui/README.md
Normal file
36
CodeGen/kubernetes/manifests/xeon/ui/README.md
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
# Deploy CodeGen with ReactUI
|
||||||
|
|
||||||
|
The README provides a step-by-step guide on how to deploy CodeGen with ReactUI, a popular React-based user interface library in Kubernetes cluster.
|
||||||
|
|
||||||
|
You can use react-codegen.yaml to deploy CodeGen with reactUI.
|
||||||
|
```
|
||||||
|
kubectl apply -f react-codegen.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prerequisites for Deploying CodeGen with ReactUI:
|
||||||
|
Before deploying the react-codegen.yaml file, ensure that you have the following prerequisites in place:
|
||||||
|
|
||||||
|
1. Kubernetes installation: Make sure that you have Kubernetes installed.
|
||||||
|
2. Configuration Values: Set the following values in react-codegen.yaml before proceeding with the deployment:
|
||||||
|
#### a. HUGGINGFACEHUB_API_TOKEN (Your HuggingFace token to download your desired model from HuggingFace):
|
||||||
|
```
|
||||||
|
# You may set the HUGGINGFACEHUB_API_TOKEN via method:
|
||||||
|
export HUGGINGFACEHUB_API_TOKEN="YourOwnToken"
|
||||||
|
cd GenAIExamples/CodeGen/kubernetes/manifests/xeon/ui/
|
||||||
|
sed -i "s/insert-your-huggingface-token-here/${HUGGINGFACEHUB_API_TOKEN}/g" react-codegen.yaml
|
||||||
|
```
|
||||||
|
#### b. Set the proxies based on your network configuration
|
||||||
|
```
|
||||||
|
# Look for http_proxy, https_proxy, no_proxy key and fill up the value with your proxy configuration.
|
||||||
|
```
|
||||||
|
3. MODEL_ID and model-volume (OPTIONAL): You may as well customize the "MODEL_ID" to use different model and model-volume for the volume to be mounted.
|
||||||
|
4. After completing these, you can proceed with the deployment of the react-codegen.yaml file.
|
||||||
|
|
||||||
|
## Verify Services:
|
||||||
|
Make sure all the pods are running, you should see total of 4 pods running:
|
||||||
|
1. codegen
|
||||||
|
2. codegen-llm-uservice
|
||||||
|
3. codegen-react-ui
|
||||||
|
4. codegen-tgi
|
||||||
|
|
||||||
|
You may open up the UI by using the codegen-react-ui endpoint in the browser.
|
||||||
280
CodeGen/kubernetes/manifests/xeon/ui/react-codegen.yaml
Normal file
280
CodeGen/kubernetes/manifests/xeon/ui/react-codegen.yaml
Normal file
@@ -0,0 +1,280 @@
|
|||||||
|
---
|
||||||
|
# Source: codegen/charts/llm-uservice/charts/tgi/templates/service.yaml
|
||||||
|
# Copyright (C) 2024 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: codegen-tgi
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: tgi-0.1.0
|
||||||
|
app.kubernetes.io/name: tgi
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.4"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
name: tgi
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: tgi
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: codegen-llm-uservice
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: llm-uservice-0.1.0
|
||||||
|
app.kubernetes.io/name: llm-uservice
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.0.0"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 9000
|
||||||
|
targetPort: 9000
|
||||||
|
protocol: TCP
|
||||||
|
name: llm-uservice
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: llm-uservice
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: codegen
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: codegen-0.1.0
|
||||||
|
app.kubernetes.io/name: codegen
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.0.0"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 7778
|
||||||
|
targetPort: 7778
|
||||||
|
protocol: TCP
|
||||||
|
name: codegen
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: codegen
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: codegen-react-ui
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: codegen-react-ui-0.1.0
|
||||||
|
app.kubernetes.io/name: react-ui
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.0.0"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- port: 80
|
||||||
|
targetPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
name: react-ui
|
||||||
|
selector:
|
||||||
|
app.kubernetes.io/name: react-ui
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: codegen-tgi
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: tgi-0.1.0
|
||||||
|
app.kubernetes.io/name: tgi
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.4"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: tgi
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: tgi
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
spec:
|
||||||
|
securityContext: {}
|
||||||
|
containers:
|
||||||
|
- name: tgi
|
||||||
|
env:
|
||||||
|
- name: MODEL_ID
|
||||||
|
value: ise-uiuc/Magicoder-S-DS-6.7B
|
||||||
|
- name: PORT
|
||||||
|
value: "80"
|
||||||
|
- name: http_proxy
|
||||||
|
value:
|
||||||
|
- name: https_proxy
|
||||||
|
value:
|
||||||
|
- name: no_proxy
|
||||||
|
value:
|
||||||
|
securityContext: {}
|
||||||
|
image: "ghcr.io/huggingface/text-generation-inference:1.4"
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /data
|
||||||
|
name: model-volume
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
resources: {}
|
||||||
|
volumes:
|
||||||
|
- name: model-volume
|
||||||
|
hostPath:
|
||||||
|
path: /mnt
|
||||||
|
type: Directory
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: codegen-llm-uservice
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: llm-uservice-0.1.0
|
||||||
|
app.kubernetes.io/name: llm-uservice
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.0.0"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: llm-uservice
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: llm-uservice
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
spec:
|
||||||
|
securityContext: {}
|
||||||
|
containers:
|
||||||
|
- name: codegen
|
||||||
|
env:
|
||||||
|
- name: TGI_LLM_ENDPOINT
|
||||||
|
value: "http://codegen-tgi:80"
|
||||||
|
- name: HUGGINGFACEHUB_API_TOKEN
|
||||||
|
value: "insert-your-huggingface-token-here"
|
||||||
|
- name: http_proxy
|
||||||
|
value:
|
||||||
|
- name: https_proxy
|
||||||
|
value:
|
||||||
|
- name: no_proxy
|
||||||
|
value:
|
||||||
|
securityContext: {}
|
||||||
|
image: "opea/llm-tgi:latest"
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: llm-uservice
|
||||||
|
containerPort: 9000
|
||||||
|
protocol: TCP
|
||||||
|
startupProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- curl
|
||||||
|
- http://codegen-tgi:80
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
failureThreshold: 120
|
||||||
|
resources: {}
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: codegen
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: codegen-0.1.0
|
||||||
|
app.kubernetes.io/name: codegen
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.0.0"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: codegen
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: codegen
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
spec:
|
||||||
|
securityContext: null
|
||||||
|
containers:
|
||||||
|
- name: codegen
|
||||||
|
env:
|
||||||
|
- name: LLM_SERVICE_HOST_IP
|
||||||
|
value: codegen-llm-uservice
|
||||||
|
- name: http_proxy
|
||||||
|
value:
|
||||||
|
- name: https_proxy
|
||||||
|
value:
|
||||||
|
- name: no_proxy
|
||||||
|
value:
|
||||||
|
securityContext: null
|
||||||
|
image: "opea/codegen:latest"
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: codegen
|
||||||
|
containerPort: 7778
|
||||||
|
protocol: TCP
|
||||||
|
resources: null
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: codegen-react-ui
|
||||||
|
labels:
|
||||||
|
helm.sh/chart: codegen-react-ui-0.1.0
|
||||||
|
app.kubernetes.io/name: react-ui
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
app.kubernetes.io/version: "1.0.0"
|
||||||
|
app.kubernetes.io/managed-by: Helm
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app.kubernetes.io/name: react-ui
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: react-ui
|
||||||
|
app.kubernetes.io/instance: codegen
|
||||||
|
spec:
|
||||||
|
securityContext: null
|
||||||
|
containers:
|
||||||
|
- name: codegen-react-ui
|
||||||
|
env:
|
||||||
|
- name: BASIC_URL
|
||||||
|
value: "http://codegen:7778/v1/codegen"
|
||||||
|
- name: http_proxy
|
||||||
|
value:
|
||||||
|
- name: https_proxy
|
||||||
|
value:
|
||||||
|
- name: no_proxy
|
||||||
|
value:
|
||||||
|
securityContext: null
|
||||||
|
image: "opea/codegen-react-ui:latest"
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
ports:
|
||||||
|
- name: react-ui
|
||||||
|
containerPort: 80
|
||||||
|
protocol: TCP
|
||||||
|
resources: null
|
||||||
@@ -22,6 +22,7 @@ function build_docker_images() {
|
|||||||
|
|
||||||
cd $WORKPATH/docker/ui
|
cd $WORKPATH/docker/ui
|
||||||
docker build --no-cache -t opea/codegen-ui:latest -f docker/Dockerfile .
|
docker build --no-cache -t opea/codegen-ui:latest -f docker/Dockerfile .
|
||||||
|
docker build --no-cache --build-arg BACKEND_SERVICE_ENDPOINT=http://${ip_address}:7778/v1/codegen -t opea/codegen--react-ui:latest -f docker/Dockerfile.react .
|
||||||
|
|
||||||
docker images
|
docker images
|
||||||
}
|
}
|
||||||
@@ -43,6 +44,7 @@ function start_services() {
|
|||||||
echo "using image repository $IMAGE_REPO and image tag $IMAGE_TAG"
|
echo "using image repository $IMAGE_REPO and image tag $IMAGE_TAG"
|
||||||
sed -i "s#image: opea/codegen:latest#image: opea/codegen:${IMAGE_TAG}#g" docker_compose.yaml
|
sed -i "s#image: opea/codegen:latest#image: opea/codegen:${IMAGE_TAG}#g" docker_compose.yaml
|
||||||
sed -i "s#image: opea/codegen-ui:latest#image: opea/codegen-ui:${IMAGE_TAG}#g" docker_compose.yaml
|
sed -i "s#image: opea/codegen-ui:latest#image: opea/codegen-ui:${IMAGE_TAG}#g" docker_compose.yaml
|
||||||
|
sed -i "s#image: opea/codegen-react-ui:latest#image: opea/codegen-react-ui:${IMAGE_TAG}#g" docker_compose.yaml
|
||||||
sed -i "s#image: opea/*#image: ${IMAGE_REPO}opea/#g" docker_compose.yaml
|
sed -i "s#image: opea/*#image: ${IMAGE_REPO}opea/#g" docker_compose.yaml
|
||||||
echo "cat docker_compose.yaml"
|
echo "cat docker_compose.yaml"
|
||||||
cat docker_compose.yaml
|
cat docker_compose.yaml
|
||||||
@@ -51,7 +53,7 @@ function start_services() {
|
|||||||
# Start Docker Containers
|
# Start Docker Containers
|
||||||
docker compose -f docker_compose.yaml up -d
|
docker compose -f docker_compose.yaml up -d
|
||||||
|
|
||||||
sleep 2m # Waits 2 minutes
|
sleep 5m # Waits 5 minutes
|
||||||
}
|
}
|
||||||
|
|
||||||
function validate_services() {
|
function validate_services() {
|
||||||
|
|||||||
@@ -15,11 +15,14 @@ function build_docker_images() {
|
|||||||
|
|
||||||
docker build -t opea/llm-tgi:latest -f comps/llms/text-generation/tgi/Dockerfile .
|
docker build -t opea/llm-tgi:latest -f comps/llms/text-generation/tgi/Dockerfile .
|
||||||
|
|
||||||
|
docker pull ghcr.io/huggingface/text-generation-inference:1.4
|
||||||
|
|
||||||
cd $WORKPATH/docker
|
cd $WORKPATH/docker
|
||||||
docker build --no-cache -t opea/codegen:latest -f Dockerfile .
|
docker build --no-cache -t opea/codegen:latest -f Dockerfile .
|
||||||
|
|
||||||
cd $WORKPATH/docker/ui
|
cd $WORKPATH/docker/ui
|
||||||
docker build --no-cache -t opea/codegen-ui:latest -f docker/Dockerfile .
|
docker build --no-cache -t opea/codegen-ui:latest -f docker/Dockerfile .
|
||||||
|
docker build --no-cache --build-arg BACKEND_SERVICE_ENDPOINT=http://${ip_address}:7778/v1/codegen -t opea/codegen-react-ui:latest -f docker/Dockerfile.react .
|
||||||
|
|
||||||
docker images
|
docker images
|
||||||
}
|
}
|
||||||
@@ -41,6 +44,7 @@ function start_services() {
|
|||||||
echo "using image repository $IMAGE_REPO and image tag $IMAGE_TAG"
|
echo "using image repository $IMAGE_REPO and image tag $IMAGE_TAG"
|
||||||
sed -i "s#image: opea/codegen:latest#image: opea/codegen:${IMAGE_TAG}#g" docker_compose.yaml
|
sed -i "s#image: opea/codegen:latest#image: opea/codegen:${IMAGE_TAG}#g" docker_compose.yaml
|
||||||
sed -i "s#image: opea/codegen-ui:latest#image: opea/codegen-ui:${IMAGE_TAG}#g" docker_compose.yaml
|
sed -i "s#image: opea/codegen-ui:latest#image: opea/codegen-ui:${IMAGE_TAG}#g" docker_compose.yaml
|
||||||
|
sed -i "s#image: opea/codegen-react-ui:latest#image: opea/codegen-react-ui:${IMAGE_TAG}#g" docker_compose.yaml
|
||||||
sed -i "s#image: opea/*#image: ${IMAGE_REPO}opea/#g" docker_compose.yaml
|
sed -i "s#image: opea/*#image: ${IMAGE_REPO}opea/#g" docker_compose.yaml
|
||||||
echo "cat docker_compose.yaml"
|
echo "cat docker_compose.yaml"
|
||||||
cat docker_compose.yaml
|
cat docker_compose.yaml
|
||||||
|
|||||||
Reference in New Issue
Block a user