diff --git a/.github/workflows/scripts/build_push.sh b/.github/workflows/scripts/build_push.sh
index 58e92a208..cb17027ad 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" == "DocSum" ];then
+ docker_build ${IMAGE_NAME}-react-ui docker/Dockerfile.react
+ fi
if [ "$MEGA_SVC" == "CodeGen" ];then
docker_build ${IMAGE_NAME}-react-ui docker/Dockerfile.react
fi
diff --git a/DocSum/assets/img/docsum-ui-react-error.png b/DocSum/assets/img/docsum-ui-react-error.png
new file mode 100644
index 000000000..de3cfedaf
Binary files /dev/null and b/DocSum/assets/img/docsum-ui-react-error.png differ
diff --git a/DocSum/assets/img/docsum-ui-react-file.png b/DocSum/assets/img/docsum-ui-react-file.png
new file mode 100644
index 000000000..d4c18ebd4
Binary files /dev/null and b/DocSum/assets/img/docsum-ui-react-file.png differ
diff --git a/DocSum/assets/img/docsum-ui-react.png b/DocSum/assets/img/docsum-ui-react.png
new file mode 100644
index 000000000..9034bc84f
Binary files /dev/null and b/DocSum/assets/img/docsum-ui-react.png differ
diff --git a/DocSum/docker/gaudi/README.md b/DocSum/docker/gaudi/README.md
index ace3c5c0d..290972d8b 100644
--- a/DocSum/docker/gaudi/README.md
+++ b/DocSum/docker/gaudi/README.md
@@ -44,12 +44,23 @@ cd GenAIExamples/DocSum/docker/ui/
docker build -t opea/docsum-ui:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f ./docker/Dockerfile .
```
+### 5. Build React UI Docker Image
+
+Build the frontend Docker image via below command:
+
+```bash
+cd GenAIExamples/DocSum/docker/ui/
+export BACKEND_SERVICE_ENDPOINT="http://${host_ip}:8888/v1/docsum"
+docker build -t opea/docsum-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 Docker Images:
1. `ghcr.io/huggingface/tgi-gaudi:2.0.1`
2. `opea/llm-docsum-tgi:latest`
3. `opea/docsum:latest`
4. `opea/docsum-ui:latest`
+5. `opea/docsum-react-ui:latest`
## 🚀 Start Microservices and MegaService
@@ -125,7 +136,7 @@ export LANGCHAIN_TRACING_V2=true
export LANGCHAIN_API_KEY=ls_...
```
-## 🚀 Launch the UI
+## 🚀 Launch the Svelte UI
Open this URL `http://{host_ip}:5173` in your browser to access the frontend.
@@ -134,3 +145,9 @@ Open this URL `http://{host_ip}:5173` in your browser to access the frontend.
Here is an example for summarizing a article.
![image](https://github.com/intel-ai-tce/GenAIExamples/assets/21761437/67ecb2ec-408d-4e81-b124-6ded6b833f55)
+
+## 🚀 Launch the React UI
+
+Open this URL `http://{host_ip}:5175` in your browser to access the frontend.
+
+![project-screenshot](../../assets/img/docsum-ui-react.png)
diff --git a/DocSum/docker/gaudi/docker_compose.yaml b/DocSum/docker/gaudi/docker_compose.yaml
index d2984a125..a381a9f42 100644
--- a/DocSum/docker/gaudi/docker_compose.yaml
+++ b/DocSum/docker/gaudi/docker_compose.yaml
@@ -71,6 +71,18 @@ services:
- DOC_BASE_URL=${BACKEND_SERVICE_ENDPOINT}
ipc: host
restart: always
+ docsum-xeon-react-ui-server:
+ image: opea/docsum-react-ui:latest
+ container_name: docsum-gaudi-react-ui-server
+ depends_on:
+ - docsum-gaudi-backend-server
+ build:
+ args:
+ - BACKEND_SERVICE_ENDPOINT=${BACKEND_SERVICE_ENDPOINT}
+ ports:
+ - "5174:80"
+ environment:
+ - DOC_BASE_URL=${BACKEND_SERVICE_ENDPOINT}
networks:
default:
diff --git a/DocSum/docker/ui/docker/Dockerfile.react b/DocSum/docker/ui/docker/Dockerfile.react
new file mode 100644
index 000000000..aa8f3fe78
--- /dev/null
+++ b/DocSum/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_DOC_SUM_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/DocSum/docker/ui/react/.env b/DocSum/docker/ui/react/.env
new file mode 100644
index 000000000..88e4996a2
--- /dev/null
+++ b/DocSum/docker/ui/react/.env
@@ -0,0 +1 @@
+VITE_DOC_SUM_URL=http://backend_address:8888/v1/docsum
\ No newline at end of file
diff --git a/DocSum/docker/ui/react/.eslintrc.cjs b/DocSum/docker/ui/react/.eslintrc.cjs
new file mode 100644
index 000000000..78174f683
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/.gitignore b/DocSum/docker/ui/react/.gitignore
new file mode 100644
index 000000000..a547bf36d
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/README.md b/DocSum/docker/ui/react/README.md
new file mode 100644
index 000000000..819469e73
--- /dev/null
+++ b/DocSum/docker/ui/react/README.md
@@ -0,0 +1,29 @@
+
Doc Summary React
+
+### 📸 Project Screenshots
+
+![project-screenshot](../../../assets/img/docsum-ui-react.png)
+![project-screenshot](../../../assets/img/docsum-ui-react-file.png)
+![project-screenshot](../../../assets/img/docsum-ui-react-error.png)
+
+🧐 Features
+
+Here're some of the project's features:
+
+- Summarizing Uploaded Files: Upload files from their local device, then click 'Generate Summary' to summarize the content of the uploaded file. The summary will be displayed on the 'Summary' box.
+- Summarizing Text via Pasting: Paste the text to be summarized into the text box, then click 'Generate Summary' to produce a condensed summary of the content, which will be displayed in the 'Summary' box on the right.
+- Scroll to Bottom: The summarized content will automatically scroll to the bottom.
+
+🛠️ Get it Running:
+
+1. Clone the repo.
+
+2. cd command to the current folder.
+
+3. Modify the required .env variables.
+ ```
+ VITE_DOC_SUM_URL = ''
+ ```
+4. Execute `npm install` to install the corresponding dependencies.
+
+5. Execute `npm run dev` in both environments
diff --git a/DocSum/docker/ui/react/index.html b/DocSum/docker/ui/react/index.html
new file mode 100644
index 000000000..bedf57052
--- /dev/null
+++ b/DocSum/docker/ui/react/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+ Opea Doc Sum
+
+
+
+
+
+
diff --git a/DocSum/docker/ui/react/nginx.conf b/DocSum/docker/ui/react/nginx.conf
new file mode 100644
index 000000000..00433fcda
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/package.json b/DocSum/docker/ui/react/package.json
new file mode 100644
index 000000000..1d88b1c6b
--- /dev/null
+++ b/DocSum/docker/ui/react/package.json
@@ -0,0 +1,52 @@
+{
+ "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.11.1",
+ "@mantine/dropzone": "^7.11.1",
+ "@mantine/hooks": "^7.11.1",
+ "@mantine/notifications": "^7.11.1",
+ "@microsoft/fetch-event-source": "^2.0.1",
+ "@reduxjs/toolkit": "^2.2.5",
+ "@tabler/icons-react": "^3.9.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/DocSum/docker/ui/react/postcss.config.cjs b/DocSum/docker/ui/react/postcss.config.cjs
new file mode 100644
index 000000000..e817f567b
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/App.scss b/DocSum/docker/ui/react/src/App.scss
new file mode 100644
index 000000000..187764a17
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/App.tsx b/DocSum/docker/ui/react/src/App.tsx
new file mode 100644
index 000000000..f2fd996bf
--- /dev/null
+++ b/DocSum/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 { IconFileText } from "@tabler/icons-react"
+import { Notifications } from '@mantine/notifications';
+import DocSum from "./components/DocSum/DocSum";
+
+const title = "Doc Summary"
+const navList: SidebarNavList = [
+ { icon: IconFileText, label: title }
+]
+
+function App() {
+
+ return (
+
+
+
+
+ )
+}
+
+export default App
diff --git a/DocSum/docker/ui/react/src/__tests__/util.test.ts b/DocSum/docker/ui/react/src/__tests__/util.test.ts
new file mode 100644
index 000000000..e67ba2c86
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/assets/opea-icon-black.svg b/DocSum/docker/ui/react/src/assets/opea-icon-black.svg
new file mode 100644
index 000000000..5c96dc762
--- /dev/null
+++ b/DocSum/docker/ui/react/src/assets/opea-icon-black.svg
@@ -0,0 +1,39 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DocSum/docker/ui/react/src/assets/opea-icon-color.svg b/DocSum/docker/ui/react/src/assets/opea-icon-color.svg
new file mode 100644
index 000000000..790151171
--- /dev/null
+++ b/DocSum/docker/ui/react/src/assets/opea-icon-color.svg
@@ -0,0 +1,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/DocSum/docker/ui/react/src/common/client.ts b/DocSum/docker/ui/react/src/common/client.ts
new file mode 100644
index 000000000..7512f73e3
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/common/util.ts b/DocSum/docker/ui/react/src/common/util.ts
new file mode 100644
index 000000000..df65b2d8e
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/components/DocSum/DocSum.tsx b/DocSum/docker/ui/react/src/components/DocSum/DocSum.tsx
new file mode 100644
index 000000000..9e7472c65
--- /dev/null
+++ b/DocSum/docker/ui/react/src/components/DocSum/DocSum.tsx
@@ -0,0 +1,153 @@
+import styleClasses from './docSum.module.scss'
+import { Button, Text, Textarea, Title } from '@mantine/core'
+import { FileUpload } from './FileUpload'
+import { useEffect, useState } from 'react'
+import Markdown from '../Shared/Markdown/Markdown'
+import { fetchEventSource } from '@microsoft/fetch-event-source'
+import { notifications } from '@mantine/notifications'
+import { DOC_SUM_URL } from '../../config'
+import { FileWithPath } from '@mantine/dropzone'
+
+
+const DocSum = () => {
+ const [isFile, setIsFile] = useState(false);
+ const [files, setFiles] = useState([])
+ const [isGenerating, setIsGenerating] = useState(false);
+ const [value, setValue] = useState('');
+ const [fileContent, setFileContent] = useState('');
+ const [response, setResponse] = useState('');
+
+ useEffect(() => {
+ if(isFile){
+ setValue('')
+ }
+ },[isFile])
+
+ useEffect(()=>{
+ if (files.length) {
+ const reader = new FileReader()
+ reader.onload = async () => {
+ const text = reader.result?.toString()
+ setFileContent(text || '')
+ };
+ reader.readAsText(files[0])
+ }
+ },[files])
+
+
+ const handleSubmit = async () => {
+ setResponse("")
+ if(!isFile && !value){
+ notifications.show({
+ color: "red",
+ id: "input",
+ message: "Please Upload Content",
+ })
+ return
+ }
+
+ setIsGenerating(true)
+ const body = {
+ messages: isFile ? fileContent : value
+ }
+ fetchEventSource(DOC_SUM_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 res = JSON.parse(msg.data)
+ const logs = res.ops;
+ logs.forEach((log: { op: string; path: string; value: string }) => {
+ if (log.op === "add") {
+ if (
+ log.value !== "" && log.path.endsWith("/streamed_output/-") && log.path.length > "/streamed_output/-".length
+ ) {
+ setResponse(prev=>prev+log.value);
+ }
+ }
+ });
+ } catch (e) {
+ console.log("something wrong in msg", e);
+ throw e;
+ }
+ }
+ },
+ onerror(err) {
+ console.log("error", err);
+ setIsGenerating(false)
+ throw err;
+ },
+ onclose() {
+ setIsGenerating(false)
+ },
+ });
+}
+
+
+ return (
+
+
+
+
+
Doc Summary
+
+
+ Please upload file or paste content for summarization.
+
+
+
+ setIsFile(false)}>Paste Text
+ setIsFile(true)}>Upload File
+
+
+
+ {isFile ? (
+
+ { setFiles(files) }} />
+
+ ) : (
+
+
+ )}
+
+
+ Generate Summary
+
+ {response && (
+
+
+
+ )}
+
+
+
+
+ )
+}
+
+export default DocSum
\ No newline at end of file
diff --git a/DocSum/docker/ui/react/src/components/DocSum/FileUpload.tsx b/DocSum/docker/ui/react/src/components/DocSum/FileUpload.tsx
new file mode 100644
index 000000000..baa77670c
--- /dev/null
+++ b/DocSum/docker/ui/react/src/components/DocSum/FileUpload.tsx
@@ -0,0 +1,67 @@
+import { Group, Text, rem } from '@mantine/core';
+import { IconUpload, IconCloudUpload, IconX, IconFile } from '@tabler/icons-react';
+import { } from '@tabler/icons-react';
+import { Dropzone, DropzoneProps, FileWithPath } from '@mantine/dropzone';
+import '@mantine/dropzone/styles.css';
+import { useState } from 'react';
+
+export function FileUpload(props: Partial) {
+ const [files, setFiles] = useState([])
+ return (
+ { setFiles(files) }}
+ onReject={() => { }}
+ maxSize={5 * 1024 ** 2}
+ multiple={false}
+ accept={[
+ "text/plain",
+ ]}
+ style={{ height: '220px', width: '100%', borderColor: 'var(--mantine-color-blue-6)' }}
+ {...props}
+ >
+
+
+
+
+
+
+
+
+ {files.length > 0 ? ( ) : ( )}
+
+ {files.length > 0 ? (
+
+ {files.map(file => (
+
+ {file.name}
+
+ ))}
+
+
+ ) : (
+
+
+ Drag your file here or click to select file
+
+
+ .txt
+
+
+
+ )}
+
+
+ );
+}
\ No newline at end of file
diff --git a/DocSum/docker/ui/react/src/components/DocSum/docSum.module.scss b/DocSum/docker/ui/react/src/components/DocSum/docSum.module.scss
new file mode 100644
index 000000000..399e97939
--- /dev/null
+++ b/DocSum/docker/ui/react/src/components/DocSum/docSum.module.scss
@@ -0,0 +1,44 @@
+// Copyright (C) 2024 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+
+@import "../../styles/styles";
+
+.spacer {
+ flex: 1 1 auto;
+}
+
+.docSumWrapper {
+ @include flex(row, nowrap, flex-start, flex-start);
+ flex: 1 1 auto;
+ height: 100%;
+ & > * {
+ height: 100%;
+ }
+ .docSumContent {
+ flex: 1 1 auto;
+ position: relative;
+ .docSumContentMessages {
+ @include absolutes;
+ @include flex(column, nowrap, normal, normal);
+ > * {
+ padding: 8px 24px;
+ }
+ .docSumTitle {
+ @include flex(row, nowrap, center, flex-start);
+ height: 60px;
+ border-bottom: 1px solid light-dark(var(--mantine-color-gray-3), var(--mantine-color-dark-4));
+ }
+ .docSumContentButtonGroup {
+ @include flex(row, nowrap, center, center);
+ height: 60px;
+ }
+ .docSumInput {
+ .docSumFileUpload {
+ @include flex(row, nowrap, center, center);
+ }
+ }
+ .docSumResult {
+ }
+ }
+ }
+}
diff --git a/DocSum/docker/ui/react/src/components/Shared/CodeRender/CodeRender.tsx b/DocSum/docker/ui/react/src/components/Shared/CodeRender/CodeRender.tsx
new file mode 100644
index 000000000..479034cec
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/components/Shared/CodeRender/codeRender.module.scss b/DocSum/docker/ui/react/src/components/Shared/CodeRender/codeRender.module.scss
new file mode 100644
index 000000000..a62f00d40
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/components/Shared/Markdown/Markdown.tsx b/DocSum/docker/ui/react/src/components/Shared/Markdown/Markdown.tsx
new file mode 100644
index 000000000..dc4b2d308
--- /dev/null
+++ b/DocSum/docker/ui/react/src/components/Shared/Markdown/Markdown.tsx
@@ -0,0 +1,58 @@
+import markdownStyles from './markdown.module.scss'
+import ReactMarkdown from 'react-markdown';
+import remarkGfm from 'remark-gfm';
+import remarkFrontmatter from 'remark-frontmatter';
+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 be undefined
+ code({ inline, className, children, }) {
+ const lang = /language-(\w+)/.exec(className || '')
+ return
+ }
+ }}
+ />)
+}
+
+export default Markdown;
\ No newline at end of file
diff --git a/DocSum/docker/ui/react/src/components/Shared/Markdown/markdown.module.scss b/DocSum/docker/ui/react/src/components/Shared/Markdown/markdown.module.scss
new file mode 100644
index 000000000..e796f836f
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/components/sidebar/sidebar.module.scss b/DocSum/docker/ui/react/src/components/sidebar/sidebar.module.scss
new file mode 100644
index 000000000..b58a253c2
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/components/sidebar/sidebar.tsx b/DocSum/docker/ui/react/src/components/sidebar/sidebar.tsx
new file mode 100644
index 000000000..f8f55fc53
--- /dev/null
+++ b/DocSum/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 (
+
+
+
+
+
+
+
+ {links}
+
+
+
+ )
+}
diff --git a/DocSum/docker/ui/react/src/config.ts b/DocSum/docker/ui/react/src/config.ts
new file mode 100644
index 000000000..d11a649de
--- /dev/null
+++ b/DocSum/docker/ui/react/src/config.ts
@@ -0,0 +1,4 @@
+// Copyright (C) 2024 Intel Corporation
+// SPDX-License-Identifier: Apache-2.0
+
+export const DOC_SUM_URL = import.meta.env.VITE_DOC_SUM_URL;
diff --git a/DocSum/docker/ui/react/src/index.scss b/DocSum/docker/ui/react/src/index.scss
new file mode 100644
index 000000000..53e71621e
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/main.tsx b/DocSum/docker/ui/react/src/main.tsx
new file mode 100644
index 000000000..ab03e5ad2
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/styles/components/_sidebar.scss b/DocSum/docker/ui/react/src/styles/components/_sidebar.scss
new file mode 100644
index 000000000..23018ee1f
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/styles/components/content.scss b/DocSum/docker/ui/react/src/styles/components/content.scss
new file mode 100644
index 000000000..9a230f249
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/styles/components/context.module.scss b/DocSum/docker/ui/react/src/styles/components/context.module.scss
new file mode 100644
index 000000000..0d9322990
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/styles/layout/_basics.scss b/DocSum/docker/ui/react/src/styles/layout/_basics.scss
new file mode 100644
index 000000000..d11b1ef21
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/styles/layout/_flex.scss b/DocSum/docker/ui/react/src/styles/layout/_flex.scss
new file mode 100644
index 000000000..18d2ce8ec
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/styles/styles.scss b/DocSum/docker/ui/react/src/styles/styles.scss
new file mode 100644
index 000000000..8028d8ad6
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/src/vite-env.d.ts b/DocSum/docker/ui/react/src/vite-env.d.ts
new file mode 100644
index 000000000..4260915f7
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/tsconfig.json b/DocSum/docker/ui/react/tsconfig.json
new file mode 100644
index 000000000..f50b75c5f
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/tsconfig.node.json b/DocSum/docker/ui/react/tsconfig.node.json
new file mode 100644
index 000000000..97ede7ee6
--- /dev/null
+++ b/DocSum/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/DocSum/docker/ui/react/vite.config.ts b/DocSum/docker/ui/react/vite.config.ts
new file mode 100644
index 000000000..c2b79a34e
--- /dev/null
+++ b/DocSum/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/DocSum/docker/xeon/README.md b/DocSum/docker/xeon/README.md
index d473ef818..b915d26e8 100644
--- a/DocSum/docker/xeon/README.md
+++ b/DocSum/docker/xeon/README.md
@@ -52,6 +52,23 @@ Then run the command `docker images`, you will have the following Docker Images:
2. `opea/docsum:latest`
3. `opea/docsum-ui:latest`
+### 4. Build React UI Docker Image
+
+Build the frontend Docker image via below command:
+
+```bash
+cd GenAIExamples/DocSum/docker/ui/
+export BACKEND_SERVICE_ENDPOINT="http://${host_ip}:8888/v1/docsum"
+docker build -t opea/docsum-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 Docker Images:
+
+1. `opea/llm-docsum-tgi:latest`
+2. `opea/docsum:latest`
+3. `opea/docsum-ui:latest`
+4. `opea/docsum-react-ui:latest`
+
## 🚀 Start Microservices and MegaService
### Setup Environment Variables
@@ -130,6 +147,13 @@ export LANGCHAIN_API_KEY=ls_...
## 🚀 Launch the UI
-Open this URL `http://{host_ip}:5173` in your browser to access the frontend.
+Open this URL `http://{host_ip}:5173` in your browser to access the svelte based frontend.
+Open this URL `http://{host_ip}:5174` in your browser to access the React based frontend.
+
+#### Svelte UI
![project-screenshot](../../assets/img/docSum_ui_text.png)
+
+#### React UI
+
+![preject-react-screenshot](../../assets/img/docsum-ui-react.png)
diff --git a/DocSum/docker/xeon/docker_compose.yaml b/DocSum/docker/xeon/docker_compose.yaml
index 8fad40f3a..6e5ab0be5 100644
--- a/DocSum/docker/xeon/docker_compose.yaml
+++ b/DocSum/docker/xeon/docker_compose.yaml
@@ -68,6 +68,18 @@ services:
- DOC_BASE_URL=${BACKEND_SERVICE_ENDPOINT}
ipc: host
restart: always
+ docsum-xeon-react-ui-server:
+ image: opea/docsum-react-ui:latest
+ container_name: docsum-xeon-react-ui-server
+ depends_on:
+ - docsum-xeon-backend-server
+ build:
+ args:
+ - BACKEND_SERVICE_ENDPOINT=${BACKEND_SERVICE_ENDPOINT}
+ ports:
+ - "5174:80"
+ ipc: host
+ restart: always
networks:
default:
diff --git a/DocSum/kubernetes/manifests/README.md b/DocSum/kubernetes/manifests/README.md
index f1da4e1d6..aba1bb116 100644
--- a/DocSum/kubernetes/manifests/README.md
+++ b/DocSum/kubernetes/manifests/README.md
@@ -4,7 +4,7 @@
> The following values must be set before you can deploy:
> HUGGINGFACEHUB_API_TOKEN
-> You can also customize the "MODEL_ID" if needed.
+> You can also customize the "MODEL_ID" and "model-volume"
> You need to make sure you have created the directory `/mnt/opea-models` to save the cached model on the node where the DocSum workload is running. Otherwise, you need to modify the `docsum.yaml` file to change the `model-volume` to a directory that exists on the node.
diff --git a/DocSum/kubernetes/manifests/xeon/ui/README.md b/DocSum/kubernetes/manifests/xeon/ui/README.md
new file mode 100644
index 000000000..4f7a2ad97
--- /dev/null
+++ b/DocSum/kubernetes/manifests/xeon/ui/README.md
@@ -0,0 +1,36 @@
+# Deploy DocSum with ReactUI
+
+The README provides a step-by-step guide on how to deploy DocSum with ReactUI, a popular React-based user interface library in Kubernetes cluster.
+
+You can use react-docsum.yaml to deploy Docsum with reactUI.
+```
+kubectl apply -f react-docsum.yaml
+```
+
+## Prerequisites for Deploying DocSum with ReactUI:
+Before deploying the react-docsum.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-docsum.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/DocSum/kubernetes/manifests/xeon/ui/
+ sed -i "s/insert-your-huggingface-token-here/${HUGGINGFACEHUB_API_TOKEN}/g" react-docsum.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-docsum.yaml file.
+
+## Verify Services:
+Make sure all the pods are running, you should see total of 4 pods running:
+1. docsum
+2. docsum-llm-uservice
+3. docsum-react-ui
+4. docsum-tgi
+
+You may open up the UI by using the docsum-react-ui endpoint in the browser.
diff --git a/DocSum/kubernetes/manifests/xeon/ui/react-docsum.yaml b/DocSum/kubernetes/manifests/xeon/ui/react-docsum.yaml
new file mode 100644
index 000000000..eb83b00b0
--- /dev/null
+++ b/DocSum/kubernetes/manifests/xeon/ui/react-docsum.yaml
@@ -0,0 +1,281 @@
+---
+# 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: docsum-tgi
+ labels:
+ helm.sh/chart: tgi-0.1.0
+ app.kubernetes.io/name: tgi
+ app.kubernetes.io/instance: docsum
+ 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: docsum
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: docsum-llm-uservice
+ labels:
+ helm.sh/chart: llm-uservice-0.1.0
+ app.kubernetes.io/name: llm-uservice
+ app.kubernetes.io/instance: docsum
+ 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: docsum
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: docsum
+ labels:
+ helm.sh/chart: docsum-0.1.0
+ app.kubernetes.io/name: docsum
+ app.kubernetes.io/instance: docsum
+ app.kubernetes.io/version: "1.0.0"
+ app.kubernetes.io/managed-by: Helm
+spec:
+ type: ClusterIP
+ ports:
+ - port: 8888
+ targetPort: 8888
+ protocol: TCP
+ name: docsum
+ selector:
+ app.kubernetes.io/name: docsum
+ app.kubernetes.io/instance: docsum
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: docsum-react-ui
+ labels:
+ helm.sh/chart: docsum-react-ui-0.1.0
+ app.kubernetes.io/name: react-ui
+ app.kubernetes.io/instance: docsum
+ 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: docsum
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: docsum-tgi
+ labels:
+ helm.sh/chart: tgi-0.1.0
+ app.kubernetes.io/name: tgi
+ app.kubernetes.io/instance: docsum
+ 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: docsum
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: tgi
+ app.kubernetes.io/instance: docsum
+ spec:
+ securityContext: {}
+ containers:
+ - name: tgi
+ env:
+ - name: MODEL_ID
+ value: Intel/neural-chat-7b-v3-3
+ - 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: docsum-llm-uservice
+ labels:
+ helm.sh/chart: llm-uservice-0.1.0
+ app.kubernetes.io/name: llm-uservice
+ app.kubernetes.io/instance: docsum
+ 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: docsum
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: llm-uservice
+ app.kubernetes.io/instance: docsum
+ spec:
+ securityContext: {}
+ containers:
+ - name: docsum
+ env:
+ - name: TGI_LLM_ENDPOINT
+ value: "http://docsum-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-docsum-tgi:latest"
+ imagePullPolicy: IfNotPresent
+ ports:
+ - name: llm-uservice
+ containerPort: 9000
+ protocol: TCP
+ startupProbe:
+ exec:
+ command:
+ - curl
+ - http://docsum-tgi:80
+ initialDelaySeconds: 5
+ periodSeconds: 5
+ failureThreshold: 120
+ resources: {}
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: docsum
+ labels:
+ helm.sh/chart: docsum-0.1.0
+ app.kubernetes.io/name: docsum
+ app.kubernetes.io/instance: docsum
+ app.kubernetes.io/version: "1.0.0"
+ app.kubernetes.io/managed-by: Helm
+spec:
+ replicas: 1
+ selector:
+ matchLabels:
+ app.kubernetes.io/name: docsum
+ app.kubernetes.io/instance: docsum
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: docsum
+ app.kubernetes.io/instance: docsum
+ spec:
+ securityContext: null
+ containers:
+ - name: docsum
+ env:
+ - name: LLM_SERVICE_HOST_IP
+ value: docsum-llm-uservice
+ - name: http_proxy
+ value:
+ - name: https_proxy
+ value:
+ - name: no_proxy
+ value:
+ securityContext: null
+ image: "opea/docsum:latest"
+ imagePullPolicy: IfNotPresent
+ ports:
+ - name: docsum
+ containerPort: 8888
+ protocol: TCP
+ resources: null
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: docsum-react-ui
+ labels:
+ helm.sh/chart: docsum-react-ui-0.1.0
+ app.kubernetes.io/name: react-ui
+ app.kubernetes.io/instance: docsum
+ 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: docsum
+ template:
+ metadata:
+ labels:
+ app.kubernetes.io/name: react-ui
+ app.kubernetes.io/instance: docsum
+ spec:
+ securityContext: null
+ containers:
+ - name: docsum-react-ui
+ env:
+ - name: DOC_BASE_URL
+ value: "http://docsum:8888/v1/docsum"
+ - name: http_proxy
+ value:
+ - name: https_proxy
+ value:
+ - name: no_proxy
+ value:
+ securityContext: null
+ image: "opea/docsum-react-ui:latest"
+ imagePullPolicy: IfNotPresent
+ ports:
+ - name: react-ui
+ containerPort: 80
+ protocol: TCP
+ resources: null
diff --git a/DocSum/tests/test_docsum_on_gaudi.sh b/DocSum/tests/test_docsum_on_gaudi.sh
index 6cbac7ad8..00333dc07 100644
--- a/DocSum/tests/test_docsum_on_gaudi.sh
+++ b/DocSum/tests/test_docsum_on_gaudi.sh
@@ -22,6 +22,7 @@ function build_docker_images() {
cd $WORKPATH/docker/ui
docker build --no-cache -t opea/docsum-ui:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
+ docker build --no-cache -t opea/docsum-react-ui:latest --build-arg BACKEND_SERVICE_ENDPOINT=http://${ip_address}:8888/v1/docsum -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/docsum:latest#image: opea/docsum:${IMAGE_TAG}#g" docker_compose.yaml
sed -i "s#image: opea/docsum-ui:latest#image: opea/docsum-ui:${IMAGE_TAG}#g" docker_compose.yaml
+ sed -i "s#image: opea/docsum-react-ui:latest#image: opea/docsum-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/DocSum/tests/test_docsum_on_xeon.sh b/DocSum/tests/test_docsum_on_xeon.sh
index e99f5f77a..8101662df 100644
--- a/DocSum/tests/test_docsum_on_xeon.sh
+++ b/DocSum/tests/test_docsum_on_xeon.sh
@@ -20,6 +20,7 @@ function build_docker_images() {
cd $WORKPATH/docker/ui
docker build --no-cache -t opea/docsum-ui:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
+ docker build --no-cache -t opea/docsum-react-ui:latest --build-arg BACKEND_SERVICE_ENDPOINT=http://${ip_address}:8888/v1/docsum -f docker/Dockerfile.react .
docker images
}
@@ -41,6 +42,7 @@ function start_services() {
echo "using image repository $IMAGE_REPO and image tag $IMAGE_TAG"
sed -i "s#image: opea/docsum:latest#image: opea/docsum:${IMAGE_TAG}#g" docker_compose.yaml
sed -i "s#image: opea/docsum-ui:latest#image: opea/docsum-ui:${IMAGE_TAG}#g" docker_compose.yaml
+ sed -i "s#image: opea/docsum-react-ui:latest#image: opea/docsum-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
@@ -49,7 +51,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() {