diff --git a/.github/workflows/scripts/build_push.sh b/.github/workflows/scripts/build_push.sh
index 8502ea6a2..58e92a208 100755
--- a/.github/workflows/scripts/build_push.sh
+++ b/.github/workflows/scripts/build_push.sh
@@ -55,6 +55,9 @@ for MEGA_SVC in $1; do
if [ "$MEGA_SVC" == "ChatQnA" ];then
docker_build ${IMAGE_NAME}-conversation-ui docker/Dockerfile.react
fi
+ if [ "$MEGA_SVC" == "CodeGen" ];then
+ docker_build ${IMAGE_NAME}-react-ui docker/Dockerfile.react
+ fi
;;
"VisualQnA")
echo "Not supported yet"
diff --git a/ChatQnA/docker/ui/docker/Dockerfile.react b/ChatQnA/docker/ui/docker/Dockerfile.react
index 277546a9b..8ec70c657 100644
--- a/ChatQnA/docker/ui/docker/Dockerfile.react
+++ b/ChatQnA/docker/ui/docker/Dockerfile.react
@@ -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
WORKDIR /usr/app/react
diff --git a/CodeGen/assets/img/codegen_react.png b/CodeGen/assets/img/codegen_react.png
new file mode 100644
index 000000000..f2417966b
Binary files /dev/null and b/CodeGen/assets/img/codegen_react.png differ
diff --git a/CodeGen/docker/gaudi/README.md b/CodeGen/docker/gaudi/README.md
index 05f0d2056..614e73751 100644
--- a/CodeGen/docker/gaudi/README.md
+++ b/CodeGen/docker/gaudi/README.md
@@ -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 .
```
+### 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:
- `opea/llm-tgi:latest`
- `opea/codegen:latest`
- `opea/codegen-ui:latest`
+- `opea/codegen-react-ui:latest`
## 🚀 Start MicroServices and MegaService
@@ -143,12 +153,12 @@ export LANGCHAIN_TRACING_V2=true
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:
```yaml
- codegen-xeon-ui-server:
+ codegen-gaudi-ui-server:
image: opea/codegen-ui:latest
...
ports:
@@ -157,6 +167,20 @@ To access the frontend, open the following URL in your browser: `http://{host_ip
![project-screenshot](../../assets/img/codeGen_ui_init.jpg)
+## 🚀 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"
+```
+
+![project-screenshot](../../assets/img/codegen_react.png)
+
## 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.
diff --git a/CodeGen/docker/gaudi/docker_compose.yaml b/CodeGen/docker/gaudi/docker_compose.yaml
index fe194822e..965bbea97 100644
--- a/CodeGen/docker/gaudi/docker_compose.yaml
+++ b/CodeGen/docker/gaudi/docker_compose.yaml
@@ -72,6 +72,19 @@ services:
ipc: host
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:
default:
driver: bridge
diff --git a/CodeGen/docker/ui/docker/Dockerfile.react b/CodeGen/docker/ui/docker/Dockerfile.react
new file mode 100644
index 000000000..04bb59fa1
--- /dev/null
+++ b/CodeGen/docker/ui/docker/Dockerfile.react
@@ -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;"]
\ No newline at end of file
diff --git a/CodeGen/docker/ui/react/.env b/CodeGen/docker/ui/react/.env
new file mode 100644
index 000000000..c5a7e3cad
--- /dev/null
+++ b/CodeGen/docker/ui/react/.env
@@ -0,0 +1 @@
+VITE_CODE_GEN_URL=http://ip_address:7778/v1/codegen
\ No newline at end of file
diff --git a/CodeGen/docker/ui/react/.eslintrc.cjs b/CodeGen/docker/ui/react/.eslintrc.cjs
new file mode 100644
index 000000000..78174f683
--- /dev/null
+++ b/CodeGen/docker/ui/react/.eslintrc.cjs
@@ -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 }],
+ },
+};
diff --git a/CodeGen/docker/ui/react/.gitignore b/CodeGen/docker/ui/react/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/CodeGen/docker/ui/react/.gitignore
@@ -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?
diff --git a/CodeGen/docker/ui/react/README.md b/CodeGen/docker/ui/react/README.md
new file mode 100644
index 000000000..5a9b07287
--- /dev/null
+++ b/CodeGen/docker/ui/react/README.md
@@ -0,0 +1,25 @@
+
Code Gen
+
+### 📸 Project Screenshots
+
+![project-screenshot](../../../assets/img/codegen_ui_react.png)
+
+🧐 Features
+
+Here're some of the project's features:
+
+- Generate code: generate the corresponding code based on the current user's input.
+
+🛠️ Get it Running:
+
+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
diff --git a/CodeGen/docker/ui/react/index.html b/CodeGen/docker/ui/react/index.html
new file mode 100644
index 000000000..fbe87e0fd
--- /dev/null
+++ b/CodeGen/docker/ui/react/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+ Conversations UI
+
+
+
+
+
+
diff --git a/CodeGen/docker/ui/react/nginx.conf b/CodeGen/docker/ui/react/nginx.conf
new file mode 100644
index 000000000..00433fcda
--- /dev/null
+++ b/CodeGen/docker/ui/react/nginx.conf
@@ -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;
+ }
+ }
+}
\ No newline at end of file
diff --git a/CodeGen/docker/ui/react/package.json b/CodeGen/docker/ui/react/package.json
new file mode 100644
index 000000000..4b2097ece
--- /dev/null
+++ b/CodeGen/docker/ui/react/package.json
@@ -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"
+ }
+}
diff --git a/CodeGen/docker/ui/react/postcss.config.cjs b/CodeGen/docker/ui/react/postcss.config.cjs
new file mode 100644
index 000000000..e817f567b
--- /dev/null
+++ b/CodeGen/docker/ui/react/postcss.config.cjs
@@ -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",
+ },
+ },
+ },
+};
diff --git a/CodeGen/docker/ui/react/src/App.scss b/CodeGen/docker/ui/react/src/App.scss
new file mode 100644
index 000000000..187764a17
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/App.scss
@@ -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;
+}
diff --git a/CodeGen/docker/ui/react/src/App.tsx b/CodeGen/docker/ui/react/src/App.tsx
new file mode 100644
index 000000000..90f3cfb8a
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/App.tsx
@@ -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 (
+
+
+
+
+ )
+}
+
+export default App
diff --git a/CodeGen/docker/ui/react/src/__tests__/util.test.ts b/CodeGen/docker/ui/react/src/__tests__/util.test.ts
new file mode 100644
index 000000000..e67ba2c86
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/__tests__/util.test.ts
@@ -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));
+ });
+});
diff --git a/CodeGen/docker/ui/react/src/assets/opea-icon-black.svg b/CodeGen/docker/ui/react/src/assets/opea-icon-black.svg
new file mode 100644
index 000000000..5c96dc762
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/assets/opea-icon-black.svg
@@ -0,0 +1,39 @@
+
+
+
diff --git a/CodeGen/docker/ui/react/src/assets/opea-icon-color.svg b/CodeGen/docker/ui/react/src/assets/opea-icon-color.svg
new file mode 100644
index 000000000..790151171
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/assets/opea-icon-color.svg
@@ -0,0 +1,40 @@
+
+
+
diff --git a/CodeGen/docker/ui/react/src/common/client.ts b/CodeGen/docker/ui/react/src/common/client.ts
new file mode 100644
index 000000000..7512f73e3
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/common/client.ts
@@ -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;
diff --git a/CodeGen/docker/ui/react/src/common/util.ts b/CodeGen/docker/ui/react/src/common/util.ts
new file mode 100644
index 000000000..df65b2d8e
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/common/util.ts
@@ -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),
+ );
+};
diff --git a/CodeGen/docker/ui/react/src/components/CodeGen/CodeGen.tsx b/CodeGen/docker/ui/react/src/components/CodeGen/CodeGen.tsx
new file mode 100644
index 000000000..8d35d89ab
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/CodeGen/CodeGen.tsx
@@ -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("")
+ const [submittedPrompt, setSubmittedPrompt] = useState("")
+ const [response,setResponse] = useState("");
+ const promptInputRef = useRef(null)
+ const scrollViewport = useRef(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] != "") {
+ 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 (
+
+
+
+
+
CodeGen
+
+
+
+ {submittedPrompt && (
+
+ )}
+ {response && (
+
+ )}
+
+
+
+
+
+
+
+ )
+}
+export default CodeGen;
diff --git a/CodeGen/docker/ui/react/src/components/CodeGen/codeGen.module.scss b/CodeGen/docker/ui/react/src/components/CodeGen/codeGen.module.scss
new file mode 100644
index 000000000..acee80b06
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/CodeGen/codeGen.module.scss
@@ -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));
+ }
+ }
+ }
+}
diff --git a/CodeGen/docker/ui/react/src/components/Message/conversationMessage.module.scss b/CodeGen/docker/ui/react/src/components/Message/conversationMessage.module.scss
new file mode 100644
index 000000000..b00649553
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/Message/conversationMessage.module.scss
@@ -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%;
+ }
+}
diff --git a/CodeGen/docker/ui/react/src/components/Message/conversationMessage.tsx b/CodeGen/docker/ui/react/src/components/Message/conversationMessage.tsx
new file mode 100644
index 000000000..94a397d98
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/Message/conversationMessage.tsx
@@ -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 (
+
+
+ {human && }
+ {!human && }
+
+
+
+ {human && "You"} {!human && "Assistant"}
+
+
+ {dateFormat()}
+
+
+
+
+ {human? message : ()}
+
+
+ )
+}
diff --git a/CodeGen/docker/ui/react/src/components/Shared/CodeRender/CodeRender.tsx b/CodeGen/docker/ui/react/src/components/Shared/CodeRender/CodeRender.tsx
new file mode 100644
index 000000000..479034cec
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/Shared/CodeRender/CodeRender.tsx
@@ -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 ? ({cleanCode}
) : (
+
+
+
+ {language || "language not detected"}
+
+
+
+ {({ copied, copy }) => (
+ } onClick={copy}>
+ {copied ? 'Copied' : 'Copy'}
+
+ )}
+
+
+
+
+
)
+ } catch (err) {
+ return (
+
+ {cleanCode}
+
+ )
+ }
+
+}
+
+
+export default CodeRender;
\ No newline at end of file
diff --git a/CodeGen/docker/ui/react/src/components/Shared/CodeRender/codeRender.module.scss b/CodeGen/docker/ui/react/src/components/Shared/CodeRender/codeRender.module.scss
new file mode 100644
index 000000000..a62f00d40
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/Shared/CodeRender/codeRender.module.scss
@@ -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;
+}
diff --git a/CodeGen/docker/ui/react/src/components/Shared/Markdown/Markdown.tsx b/CodeGen/docker/ui/react/src/components/Shared/Markdown/Markdown.tsx
new file mode 100644
index 000000000..6331c6d08
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/Shared/Markdown/Markdown.tsx
@@ -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 (
+ {
+ return (
+
+ {children}
+
+ );
+ },
+ a: ({ children, ...props }) => {
+ return (
+
+ {children}
+
+ );
+ },
+ table: ({ children, ...props }) => {
+ return (
+
+ );
+ },
+ //@ts-expect-error inline can undefined sometimes
+ code({ inline, className, children, }) {
+ const lang = /language-(\w+)/.exec(className || '')
+ // if (lang && lang[1] === "mermaid") {
+ // return
+ // }
+ return
+ }
+ }}
+ />)
+}
+
+export default Markdown;
\ No newline at end of file
diff --git a/CodeGen/docker/ui/react/src/components/Shared/Markdown/markdown.module.scss b/CodeGen/docker/ui/react/src/components/Shared/Markdown/markdown.module.scss
new file mode 100644
index 000000000..e796f836f
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/Shared/Markdown/markdown.module.scss
@@ -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 */
+ }
+}
diff --git a/CodeGen/docker/ui/react/src/components/sidebar/sidebar.module.scss b/CodeGen/docker/ui/react/src/components/sidebar/sidebar.module.scss
new file mode 100644
index 000000000..b58a253c2
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/sidebar/sidebar.module.scss
@@ -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;
+}
diff --git a/CodeGen/docker/ui/react/src/components/sidebar/sidebar.tsx b/CodeGen/docker/ui/react/src/components/sidebar/sidebar.tsx
new file mode 100644
index 000000000..f8f55fc53
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/components/sidebar/sidebar.tsx
@@ -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 (
+
+
+
+
+
+ )
+}
+
+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) => (
+ setActive(index)} />
+ ))
+
+ return (
+
+ )
+}
diff --git a/CodeGen/docker/ui/react/src/config.ts b/CodeGen/docker/ui/react/src/config.ts
new file mode 100644
index 000000000..f8662d1ab
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/config.ts
@@ -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;
diff --git a/CodeGen/docker/ui/react/src/index.scss b/CodeGen/docker/ui/react/src/index.scss
new file mode 100644
index 000000000..53e71621e
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/index.scss
@@ -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;
+}
diff --git a/CodeGen/docker/ui/react/src/main.tsx b/CodeGen/docker/ui/react/src/main.tsx
new file mode 100644
index 000000000..ab03e5ad2
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/main.tsx
@@ -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(
+
+
+
+)
diff --git a/CodeGen/docker/ui/react/src/styles/components/_context.scss b/CodeGen/docker/ui/react/src/styles/components/_context.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/CodeGen/docker/ui/react/src/styles/components/_sidebar.scss b/CodeGen/docker/ui/react/src/styles/components/_sidebar.scss
new file mode 100644
index 000000000..23018ee1f
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/styles/components/_sidebar.scss
@@ -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);
+}
diff --git a/CodeGen/docker/ui/react/src/styles/components/content.scss b/CodeGen/docker/ui/react/src/styles/components/content.scss
new file mode 100644
index 000000000..9a230f249
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/styles/components/content.scss
@@ -0,0 +1,5 @@
+@mixin textWrapEllipsis {
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ overflow: hidden;
+}
diff --git a/CodeGen/docker/ui/react/src/styles/components/context.module.scss b/CodeGen/docker/ui/react/src/styles/components/context.module.scss
new file mode 100644
index 000000000..0d9322990
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/styles/components/context.module.scss
@@ -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);
+ }
+ }
+ }
+ }
+}
diff --git a/CodeGen/docker/ui/react/src/styles/layout/_basics.scss b/CodeGen/docker/ui/react/src/styles/layout/_basics.scss
new file mode 100644
index 000000000..d11b1ef21
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/styles/layout/_basics.scss
@@ -0,0 +1,7 @@
+@mixin absolutes {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
diff --git a/CodeGen/docker/ui/react/src/styles/layout/_flex.scss b/CodeGen/docker/ui/react/src/styles/layout/_flex.scss
new file mode 100644
index 000000000..18d2ce8ec
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/styles/layout/_flex.scss
@@ -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;
+}
diff --git a/CodeGen/docker/ui/react/src/styles/styles.scss b/CodeGen/docker/ui/react/src/styles/styles.scss
new file mode 100644
index 000000000..8028d8ad6
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/styles/styles.scss
@@ -0,0 +1,5 @@
+// Copyright (C) 2024 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+
+@import "layout/flex";
+@import "layout/basics";
diff --git a/CodeGen/docker/ui/react/src/vite-env.d.ts b/CodeGen/docker/ui/react/src/vite-env.d.ts
new file mode 100644
index 000000000..4260915f7
--- /dev/null
+++ b/CodeGen/docker/ui/react/src/vite-env.d.ts
@@ -0,0 +1,4 @@
+// Copyright (C) 2024 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+
+///
diff --git a/CodeGen/docker/ui/react/tsconfig.json b/CodeGen/docker/ui/react/tsconfig.json
new file mode 100644
index 000000000..f50b75c5f
--- /dev/null
+++ b/CodeGen/docker/ui/react/tsconfig.json
@@ -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" }]
+}
diff --git a/CodeGen/docker/ui/react/tsconfig.node.json b/CodeGen/docker/ui/react/tsconfig.node.json
new file mode 100644
index 000000000..97ede7ee6
--- /dev/null
+++ b/CodeGen/docker/ui/react/tsconfig.node.json
@@ -0,0 +1,11 @@
+{
+ "compilerOptions": {
+ "composite": true,
+ "skipLibCheck": true,
+ "module": "ESNext",
+ "moduleResolution": "bundler",
+ "allowSyntheticDefaultImports": true,
+ "strict": true
+ },
+ "include": ["vite.config.ts"]
+}
diff --git a/CodeGen/docker/ui/react/vite.config.ts b/CodeGen/docker/ui/react/vite.config.ts
new file mode 100644
index 000000000..c2b79a34e
--- /dev/null
+++ b/CodeGen/docker/ui/react/vite.config.ts
@@ -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,
+ },
+});
diff --git a/CodeGen/docker/xeon/README.md b/CodeGen/docker/xeon/README.md
index 7ed57c671..75aeaafbb 100644
--- a/CodeGen/docker/xeon/README.md
+++ b/CodeGen/docker/xeon/README.md
@@ -174,6 +174,20 @@ Here is an example of running CodeGen in the UI:
![project-screenshot](../../assets/img/codeGen_ui_response.png)
+## 🚀 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"
+```
+
+![project-screenshot](../../assets/img/codegen_react.png)
+
## 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.
diff --git a/CodeGen/docker/xeon/docker_compose.yaml b/CodeGen/docker/xeon/docker_compose.yaml
index a9357d5b6..c6c373c92 100644
--- a/CodeGen/docker/xeon/docker_compose.yaml
+++ b/CodeGen/docker/xeon/docker_compose.yaml
@@ -66,6 +66,18 @@ services:
- BASIC_URL=${BACKEND_SERVICE_ENDPOINT}
ipc: host
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:
default:
diff --git a/CodeGen/kubernetes/manifests/xeon/ui/README.md b/CodeGen/kubernetes/manifests/xeon/ui/README.md
new file mode 100644
index 000000000..dce34d335
--- /dev/null
+++ b/CodeGen/kubernetes/manifests/xeon/ui/README.md
@@ -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.
diff --git a/CodeGen/kubernetes/manifests/xeon/ui/react-codegen.yaml b/CodeGen/kubernetes/manifests/xeon/ui/react-codegen.yaml
new file mode 100644
index 000000000..874893bb4
--- /dev/null
+++ b/CodeGen/kubernetes/manifests/xeon/ui/react-codegen.yaml
@@ -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
diff --git a/CodeGen/tests/test_codegen_on_gaudi.sh b/CodeGen/tests/test_codegen_on_gaudi.sh
index 846252d13..2f597538c 100644
--- a/CodeGen/tests/test_codegen_on_gaudi.sh
+++ b/CodeGen/tests/test_codegen_on_gaudi.sh
@@ -22,6 +22,7 @@ function build_docker_images() {
cd $WORKPATH/docker/ui
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
}
@@ -43,6 +44,7 @@ function start_services() {
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-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
echo "cat docker_compose.yaml"
cat docker_compose.yaml
@@ -51,7 +53,7 @@ function start_services() {
# Start Docker Containers
docker compose -f docker_compose.yaml up -d
- sleep 2m # Waits 2 minutes
+ sleep 5m # Waits 5 minutes
}
function validate_services() {
diff --git a/CodeGen/tests/test_codegen_on_xeon.sh b/CodeGen/tests/test_codegen_on_xeon.sh
index 88b008e3a..c6b4e263d 100644
--- a/CodeGen/tests/test_codegen_on_xeon.sh
+++ b/CodeGen/tests/test_codegen_on_xeon.sh
@@ -15,11 +15,14 @@ function build_docker_images() {
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
docker build --no-cache -t opea/codegen:latest -f Dockerfile .
cd $WORKPATH/docker/ui
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
}
@@ -41,6 +44,7 @@ function start_services() {
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-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
echo "cat docker_compose.yaml"
cat docker_compose.yaml