Refactor Document Summarization Example with Microservice (#151)
Signed-off-by: zehao-intel <zehao.huang@intel.com> Co-authored-by: lvliang-intel <liang1.lv@intel.com> Co-authored-by: chensuyue <suyue.chen@intel.com>
57
.github/workflows/DocSum_gaudi.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: DocSum E2E test on Gaudi
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- DocSum/microservice/gaudi/**
|
||||
- DocSum/tests/test_docsum_on_gaudi.sh
|
||||
- "!**.md"
|
||||
- "!**/ui/**"
|
||||
- .github/workflows/DocSum_gaudi.yml
|
||||
workflow_dispatch:
|
||||
|
||||
# If there is a new commit, the previous jobs will be canceled
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
DocSum-Gaudi:
|
||||
runs-on: aise-cluster
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: "refs/pull/${{ github.event.number }}/merge"
|
||||
|
||||
- name: Run Test
|
||||
env:
|
||||
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
|
||||
AISE_CLUSTER_01_2_IP: ${{ secrets.AISE_CLUSTER_01_2_IP }}
|
||||
run: |
|
||||
cd ${{ github.workspace }}/DocSum/tests
|
||||
timeout 20m bash test_docsum_on_gaudi.sh
|
||||
|
||||
- name: Clean Up Container
|
||||
if: cancelled() || failure()
|
||||
run: |
|
||||
cd ${{ github.workspace }}/DocSum/microservice/gaudi
|
||||
container_list=$(cat docker_compose.yaml | grep container_name | cut -d':' -f2)
|
||||
for container_name in $container_list; do
|
||||
cid=$(docker ps -aq --filter "name=$container_name")
|
||||
if [[ ! -z "$cid" ]]; then docker stop $cid && docker rm $cid && sleep 1s; fi
|
||||
done
|
||||
|
||||
- name: Publish pipeline artifact
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/DocSum/tests/*.log
|
||||
@@ -1,17 +1,18 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: DocSum-test
|
||||
name: DocSum E2E test on Xeon
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- DocSum/**
|
||||
- DocSum/microservice/xeon/**
|
||||
- DocSum/tests/test_docsum_on_xeon.sh
|
||||
- "!**.md"
|
||||
- "!**/ui/**"
|
||||
- .github/workflows/DocSum.yml
|
||||
- .github/workflows/DocSum_xeon.yml
|
||||
workflow_dispatch:
|
||||
|
||||
# If there is a new commit, the previous jobs will be canceled
|
||||
@@ -20,12 +21,8 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
DocSum:
|
||||
DocSum-Xeon:
|
||||
runs-on: aise-cluster
|
||||
strategy:
|
||||
matrix:
|
||||
job_name: ["langchain"]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
@@ -38,13 +35,23 @@ jobs:
|
||||
- name: Run Test
|
||||
env:
|
||||
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
|
||||
AISE_CLUSTER_01_2_IP: ${{ secrets.AISE_CLUSTER_01_2_IP }}
|
||||
run: |
|
||||
cd ${{ github.workspace }}/DocSum/tests
|
||||
bash test_${{ matrix.job_name }}_inference.sh
|
||||
timeout 20m bash test_docsum_on_xeon.sh
|
||||
|
||||
- name: Clean Up Container
|
||||
if: cancelled() || failure()
|
||||
run: |
|
||||
cd ${{ github.workspace }}/DocSum/microservice/xeon
|
||||
container_list=$(cat docker_compose.yaml | grep container_name | cut -d':' -f2)
|
||||
for container_name in $container_list; do
|
||||
cid=$(docker ps -aq --filter "name=$container_name")
|
||||
if [[ ! -z "$cid" ]]; then docker stop $cid && docker rm $cid && sleep 1s; fi
|
||||
done
|
||||
|
||||
- name: Publish pipeline artifact
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.job_name }}
|
||||
path: ${{ github.workspace }}/DocSum/tests/*.log
|
||||
@@ -12,7 +12,8 @@ repos:
|
||||
exclude: |
|
||||
(?x)^(
|
||||
ChatQnA/ui/svelte/tsconfig.json|
|
||||
SearchQnA/ui/svelte/tsconfig.json
|
||||
SearchQnA/ui/svelte/tsconfig.json|
|
||||
DocSum/ui/svelte/tsconfig.json
|
||||
)$
|
||||
- id: check-yaml
|
||||
- id: debug-statements
|
||||
|
||||
124
DocSum/README.md
@@ -1,4 +1,4 @@
|
||||
# Document Summarization
|
||||
# Document Summarization Application
|
||||
|
||||
In a world where data, information, and legal complexities is prevalent, the volume of legal documents is growing rapidly. Law firms, legal professionals, and businesses are dealing with an ever-increasing number of legal texts, including contracts, court rulings, statutes, and regulations.
|
||||
These documents contain important insights, but understanding them can be overwhelming. This is where the demand for legal document summarization comes in.
|
||||
@@ -11,124 +11,14 @@ The document summarization architecture shows below:
|
||||
|
||||

|
||||
|
||||
# Environment Setup
|
||||
# Deploy Document Summarization Service
|
||||
|
||||
To use [🤗 text-generation-inference](https://github.com/huggingface/text-generation-inference) on Habana Gaudi/Gaudi2, please follow these steps:
|
||||
The Document Summarization service can be effortlessly deployed on either Intel Gaudi2 or Intel XEON Scalable Processors.
|
||||
|
||||
## Build TGI Gaudi Docker Image
|
||||
## Deploy Document Summarization on Gaudi
|
||||
|
||||
```bash
|
||||
bash ./serving/tgi_gaudi/build_docker.sh
|
||||
```
|
||||
Refer to the [Gaudi Guide](./microservice/gaudi/README.md) for instructions on deploying Document Summarization on Gaudi.
|
||||
|
||||
## Launch TGI Gaudi Service
|
||||
## Deploy Document Summarization on Xeon
|
||||
|
||||
### Launch a local server instance on 1 Gaudi card:
|
||||
|
||||
```bash
|
||||
bash ./serving/tgi_gaudi/launch_tgi_service.sh
|
||||
```
|
||||
|
||||
For gated models such as `LLAMA-2`, you will have to pass -e HUGGING_FACE_HUB_TOKEN=\<token\> to the docker run command above with a valid Hugging Face Hub read token.
|
||||
|
||||
Please follow this link [huggingface token](https://huggingface.co/docs/hub/security-tokens) to get the access token and export `HUGGINGFACEHUB_API_TOKEN` environment with the token.
|
||||
|
||||
```bash
|
||||
export HUGGINGFACEHUB_API_TOKEN=<token>
|
||||
```
|
||||
|
||||
### Launch a local server instance on 8 Gaudi cards:
|
||||
|
||||
```bash
|
||||
bash ./serving/tgi_gaudi/launch_tgi_service.sh 8
|
||||
```
|
||||
|
||||
### Customize TGI Gaudi Service
|
||||
|
||||
The ./serving/tgi_gaudi/launch_tgi_service.sh script accepts three parameters:
|
||||
|
||||
- num_cards: The number of Gaudi cards to be utilized, ranging from 1 to 8. The default is set to 1.
|
||||
- port_number: The port number assigned to the TGI Gaudi endpoint, with the default being 8080.
|
||||
- model_name: The model name utilized for LLM, with the default set to "Intel/neural-chat-7b-v3-3".
|
||||
|
||||
You have the flexibility to customize these parameters according to your specific needs. Additionally, you can set the TGI Gaudi endpoint by exporting the environment variable `TGI_ENDPOINT`:
|
||||
|
||||
```bash
|
||||
export TGI_ENDPOINT="http://xxx.xxx.xxx.xxx:8080"
|
||||
```
|
||||
|
||||
## Launch Document Summary Docker
|
||||
|
||||
### Build Document Summary Docker Image (Optional)
|
||||
|
||||
```bash
|
||||
cd langchain/docker/
|
||||
bash ./build_docker.sh
|
||||
cd ../../
|
||||
```
|
||||
|
||||
### Launch Document Summary Docker
|
||||
|
||||
```bash
|
||||
docker run -it --net=host --ipc=host -e http_proxy=${http_proxy} -e https_proxy=${https_proxy} -v /var/run/docker.sock:/var/run/docker.sock intel/gen-ai-examples:document-summarize bash
|
||||
```
|
||||
|
||||
# Start Document Summary Server
|
||||
|
||||
## Start the Backend Service
|
||||
|
||||
Make sure TGI-Gaudi service is running. Launch the backend service:
|
||||
|
||||
```bash
|
||||
export HUGGINGFACEHUB_API_TOKEN=<token>
|
||||
nohup python app/server.py &
|
||||
```
|
||||
|
||||
Then you can make requests like below to check the DocSum backend service status:
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8000/v1/text_summarize \
|
||||
-X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"text":"Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}'
|
||||
```
|
||||
|
||||
## Start the Frontend Service
|
||||
|
||||
Navigate to the "ui" folder and execute the following commands to start the frontend GUI:
|
||||
|
||||
```bash
|
||||
cd ui
|
||||
sudo apt-get install npm && \
|
||||
npm install -g n && \
|
||||
n stable && \
|
||||
hash -r && \
|
||||
npm install -g npm@latest
|
||||
```
|
||||
|
||||
For CentOS, please use the following commands instead:
|
||||
|
||||
```bash
|
||||
curl -sL https://rpm.nodesource.com/setup_20.x | sudo bash -
|
||||
sudo yum install -y nodejs
|
||||
```
|
||||
|
||||
Update the `BASIC_URL` environment variable in the `.env` file by replacing the IP address '127.0.0.1' with the actual IP address.
|
||||
|
||||
Run the following command to install the required dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
Start the development server by executing the following command:
|
||||
|
||||
```bash
|
||||
nohup npm run dev &
|
||||
```
|
||||
|
||||
This will initiate the frontend service and launch the application.
|
||||
|
||||
#
|
||||
|
||||
SCRIPT USAGE NOTICE: By downloading and using any script file included with the associated software package (such as files with .bat, .cmd, or .JS extensions, Docker files, or any other type of file that, when executed, automatically downloads and/or installs files onto your system) (the “Script File”), it is your obligation to review the Script File to understand what files (e.g., other software, AI models, AI Datasets) the Script File will download to your system (“Downloaded Files”). Furthermore, by downloading and using the Downloaded Files, even if they are installed through a silent install, you agree to any and all terms and conditions associated with such files, including but not limited to, license terms, notices, or disclaimers.
|
||||
Refer to the [Xeon Guide](./microservice/xeon/README.md) for instructions on deploying Document Summarization on Xeon.
|
||||
|
||||
134
DocSum/depracated/README.md
Normal file
@@ -0,0 +1,134 @@
|
||||
# Document Summarization
|
||||
|
||||
In a world where data, information, and legal complexities is prevalent, the volume of legal documents is growing rapidly. Law firms, legal professionals, and businesses are dealing with an ever-increasing number of legal texts, including contracts, court rulings, statutes, and regulations.
|
||||
These documents contain important insights, but understanding them can be overwhelming. This is where the demand for legal document summarization comes in.
|
||||
|
||||
Large Language Models (LLMs) have revolutionized the way we interact with text, LLMs can be used to create summaries of news articles, research papers, technical documents, and other types of text. Suppose you have a set of documents (PDFs, Notion pages, customer questions, etc.) and you want to summarize the content. In this example use case, we use LangChain to apply some summarization strategies and run LLM inference using Text Generation Inference on Intel Xeon and Gaudi2.
|
||||
|
||||
The document summarization architecture shows below:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
# Environment Setup
|
||||
|
||||
To use [🤗 text-generation-inference](https://github.com/huggingface/text-generation-inference) on Habana Gaudi/Gaudi2, please follow these steps:
|
||||
|
||||
## Build TGI Gaudi Docker Image
|
||||
|
||||
```bash
|
||||
bash ./serving/tgi_gaudi/build_docker.sh
|
||||
```
|
||||
|
||||
## Launch TGI Gaudi Service
|
||||
|
||||
### Launch a local server instance on 1 Gaudi card:
|
||||
|
||||
```bash
|
||||
bash ./serving/tgi_gaudi/launch_tgi_service.sh
|
||||
```
|
||||
|
||||
For gated models such as `LLAMA-2`, you will have to pass -e HUGGING_FACE_HUB_TOKEN=\<token\> to the docker run command above with a valid Hugging Face Hub read token.
|
||||
|
||||
Please follow this link [huggingface token](https://huggingface.co/docs/hub/security-tokens) to get the access token and export `HUGGINGFACEHUB_API_TOKEN` environment with the token.
|
||||
|
||||
```bash
|
||||
export HUGGINGFACEHUB_API_TOKEN=<token>
|
||||
```
|
||||
|
||||
### Launch a local server instance on 8 Gaudi cards:
|
||||
|
||||
```bash
|
||||
bash ./serving/tgi_gaudi/launch_tgi_service.sh 8
|
||||
```
|
||||
|
||||
### Customize TGI Gaudi Service
|
||||
|
||||
The ./serving/tgi_gaudi/launch_tgi_service.sh script accepts three parameters:
|
||||
|
||||
- num_cards: The number of Gaudi cards to be utilized, ranging from 1 to 8. The default is set to 1.
|
||||
- port_number: The port number assigned to the TGI Gaudi endpoint, with the default being 8080.
|
||||
- model_name: The model name utilized for LLM, with the default set to "Intel/neural-chat-7b-v3-3".
|
||||
|
||||
You have the flexibility to customize these parameters according to your specific needs. Additionally, you can set the TGI Gaudi endpoint by exporting the environment variable `TGI_ENDPOINT`:
|
||||
|
||||
```bash
|
||||
export TGI_ENDPOINT="http://xxx.xxx.xxx.xxx:8080"
|
||||
```
|
||||
|
||||
## Launch Document Summary Docker
|
||||
|
||||
### Build Document Summary Docker Image (Optional)
|
||||
|
||||
```bash
|
||||
cd langchain/docker/
|
||||
bash ./build_docker.sh
|
||||
cd ../../
|
||||
```
|
||||
|
||||
### Launch Document Summary Docker
|
||||
|
||||
```bash
|
||||
docker run -it --net=host --ipc=host -e http_proxy=${http_proxy} -e https_proxy=${https_proxy} -v /var/run/docker.sock:/var/run/docker.sock intel/gen-ai-examples:document-summarize bash
|
||||
```
|
||||
|
||||
# Start Document Summary Server
|
||||
|
||||
## Start the Backend Service
|
||||
|
||||
Make sure TGI-Gaudi service is running. Launch the backend service:
|
||||
|
||||
```bash
|
||||
export HUGGINGFACEHUB_API_TOKEN=<token>
|
||||
nohup python app/server.py &
|
||||
```
|
||||
|
||||
Then you can make requests like below to check the DocSum backend service status:
|
||||
|
||||
```bash
|
||||
curl http://127.0.0.1:8000/v1/text_summarize \
|
||||
-X POST \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"text":"Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}'
|
||||
```
|
||||
|
||||
## Start the Frontend Service
|
||||
|
||||
Navigate to the "ui" folder and execute the following commands to start the frontend GUI:
|
||||
|
||||
```bash
|
||||
cd ui
|
||||
sudo apt-get install npm && \
|
||||
npm install -g n && \
|
||||
n stable && \
|
||||
hash -r && \
|
||||
npm install -g npm@latest
|
||||
```
|
||||
|
||||
For CentOS, please use the following commands instead:
|
||||
|
||||
```bash
|
||||
curl -sL https://rpm.nodesource.com/setup_20.x | sudo bash -
|
||||
sudo yum install -y nodejs
|
||||
```
|
||||
|
||||
Update the `BASIC_URL` environment variable in the `.env` file by replacing the IP address '127.0.0.1' with the actual IP address.
|
||||
|
||||
Run the following command to install the required dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
Start the development server by executing the following command:
|
||||
|
||||
```bash
|
||||
nohup npm run dev &
|
||||
```
|
||||
|
||||
This will initiate the frontend service and launch the application.
|
||||
|
||||
#
|
||||
|
||||
SCRIPT USAGE NOTICE: By downloading and using any script file included with the associated software package (such as files with .bat, .cmd, or .JS extensions, Docker files, or any other type of file that, when executed, automatically downloads and/or installs files onto your system) (the “Script File”), it is your obligation to review the Script File to understand what files (e.g., other software, AI models, AI Datasets) the Script File will download to your system (“Downloaded Files”). Furthermore, by downloading and using the Downloaded Files, even if they are installed through a silent install, you agree to any and all terms and conditions associated with such files, including but not limited to, license terms, notices, or disclaimers.
|
||||
0
DocSum/langchain/docker/build_docker.sh → DocSum/depracated/langchain/docker/build_docker.sh
Executable file → Normal file
1
DocSum/depracated/ui/svelte/.env
Normal file
@@ -0,0 +1 @@
|
||||
BASIC_URL = 'http://x.x.x.x:yyyy'
|
||||
30
DocSum/depracated/ui/svelte/README.md
Normal file
@@ -0,0 +1,30 @@
|
||||
<h1 align="center" id="title">Doc Summary</h1>
|
||||
|
||||
### 📸 Project Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
<h2>🧐 Features</h2>
|
||||
|
||||
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.
|
||||
|
||||
<h2>🛠️ Get it Running:</h2>
|
||||
|
||||
1. Clone the repo.
|
||||
|
||||
2. cd command to the current folder.
|
||||
|
||||
3. Modify the required .env variables.
|
||||
```
|
||||
BASIC_URL = ''
|
||||
```
|
||||
4. Execute `npm install` to install the corresponding dependencies.
|
||||
|
||||
5. Execute `npm run dev` in both environments
|
||||
53
DocSum/depracated/ui/svelte/package.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"name": "doc-summary",
|
||||
"version": "0.0.1",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build && npm run package",
|
||||
"preview": "vite preview",
|
||||
"package": "svelte-kit sync && svelte-package && publint",
|
||||
"prepublishOnly": "npm run package",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"svelte": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"!dist/**/*.test.*",
|
||||
"!dist/**/*.spec.*"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"svelte": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/package": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"flowbite": "^2.3.0",
|
||||
"flowbite-svelte": "^0.38.5",
|
||||
"flowbite-svelte-icons": "^1.4.0",
|
||||
"postcss": "^8.4.32",
|
||||
"postcss-load-config": "^5.0.2",
|
||||
"publint": "^0.1.9",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte-check": "^3.6.0",
|
||||
"tailwindcss": "^3.3.6",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.0.11"
|
||||
},
|
||||
"svelte": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"sse.js": "^0.6.1",
|
||||
"svelte-notifications": "^0.9.98"
|
||||
}
|
||||
}
|
||||
27
DocSum/depracated/ui/svelte/postcss.config.cjs
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
const tailwindcss = require("tailwindcss");
|
||||
const autoprefixer = require("autoprefixer");
|
||||
|
||||
const config = {
|
||||
plugins: [
|
||||
//Some plugins, like tailwindcss/nesting, need to run before Tailwind,
|
||||
tailwindcss(),
|
||||
//But others, like autoprefixer, need to run after,
|
||||
autoprefixer,
|
||||
],
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
27
DocSum/depracated/ui/svelte/src/app.d.ts
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
28
DocSum/depracated/ui/svelte/src/app.html
Normal file
@@ -0,0 +1,28 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div>%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 910 B After Width: | Height: | Size: 910 B |
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
26
DocSum/depracated/ui/svelte/src/lib/shared/Utils.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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.
|
||||
|
||||
export function scrollToBottom(scrollToDiv: HTMLElement) {
|
||||
if (scrollToDiv) {
|
||||
setTimeout(
|
||||
() =>
|
||||
scrollToDiv.scroll({
|
||||
behavior: "auto",
|
||||
top: scrollToDiv.scrollHeight,
|
||||
}),
|
||||
100,
|
||||
);
|
||||
}
|
||||
}
|
||||
25
DocSum/depracated/ui/svelte/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,25 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script>
|
||||
import "../app.pcss";
|
||||
import Notifications from "svelte-notifications";
|
||||
|
||||
</script>
|
||||
|
||||
<Notifications>
|
||||
<slot />
|
||||
</Notifications>
|
||||
94
DocSum/depracated/ui/svelte/src/routes/+page.svelte
Normal file
@@ -0,0 +1,94 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import Header from "$lib/header.svelte";
|
||||
import Doc from "$lib/doc.svelte";
|
||||
import Summary from "$lib/summary.svelte";
|
||||
import { fetchTextStream } from "$lib/shared/Network.js";
|
||||
import { loading } from "$lib/shared/Store.js";
|
||||
import { onMount } from "svelte";
|
||||
import { scrollToBottom } from "$lib/shared/Utils.js";
|
||||
|
||||
let messages = '';
|
||||
let scrollToDiv: HTMLDivElement;
|
||||
|
||||
onMount(() => {
|
||||
scrollToDiv = document
|
||||
.querySelector("#editor")!
|
||||
console.log('scrollToDiv', scrollToDiv);
|
||||
|
||||
})
|
||||
|
||||
const callTextStream = async (
|
||||
query: string,
|
||||
urlSuffix: string,
|
||||
params: string
|
||||
) => {
|
||||
messages = "";
|
||||
const eventSource = await fetchTextStream(query, urlSuffix, params);
|
||||
|
||||
eventSource.addEventListener("message", (e: any) => {
|
||||
let Msg = e.data;
|
||||
if (Msg !== "[DONE]") {
|
||||
let res = JSON.parse(Msg);
|
||||
let logs = res.ops;
|
||||
|
||||
logs.forEach((log: { op: string; path: string; value: any }) => {
|
||||
if (log.op === "add") {
|
||||
if (
|
||||
log.value !== "</s>" && log.path.endsWith("/streamed_output/-") && log.path.length > "/streamed_output/-".length
|
||||
) {
|
||||
messages += log.value;
|
||||
scrollToBottom(scrollToDiv)
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
loading.set(false);
|
||||
scrollToBottom(scrollToDiv)
|
||||
}
|
||||
});
|
||||
eventSource.stream();
|
||||
};
|
||||
|
||||
async function handleGenerateSummary(e) {
|
||||
if (e.detail.mode === "file") {
|
||||
await callTextStream(e.detail.value, "/file_summarize", "doc_id");
|
||||
} else if (e.detail.mode === "text") {
|
||||
await callTextStream(e.detail.value, "/text_summarize", "text");
|
||||
}
|
||||
}
|
||||
|
||||
function handleClearMsg(e) {
|
||||
if (e.detail.status) {
|
||||
messages = "";
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="h-full">
|
||||
<Header />
|
||||
<p class="m-7 sm:mb-0 text-gray-500 font-semibold xl:m-8">Please upload file or paste content for summarization.</p>
|
||||
<div class="mt-2 m-6 grid grid-cols-3 gap-8 h-full">
|
||||
<div class="col-span-2 h-full">
|
||||
<Doc on:generateSummary={handleGenerateSummary} on:clearMsg={handleClearMsg}/>
|
||||
</div>
|
||||
<div class="col-span-1">
|
||||
<Summary chatMessage={messages} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
BIN
DocSum/depracated/ui/svelte/static/favicon.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
35
DocSum/depracated/ui/svelte/svelte.config.js
Normal file
@@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import adapter from "@sveltejs/adapter-auto";
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: [vitePreprocess({})],
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter(),
|
||||
env: {
|
||||
publicPrefix: "",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
43
DocSum/depracated/ui/svelte/tailwind.config.cjs
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
const config = {
|
||||
content: ["./src/**/*.{html,js,svelte,ts}", "./node_modules/flowbite-svelte/**/*.{html,js,svelte,ts}"],
|
||||
|
||||
plugins: [require("flowbite/plugin")],
|
||||
|
||||
darkMode: "class",
|
||||
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
// flowbite-svelte
|
||||
primary: {
|
||||
50: "#f2f8ff",
|
||||
100: "#eef5ff",
|
||||
200: "#deecff",
|
||||
300: "#cce2ff",
|
||||
400: "#add0ff",
|
||||
500: "#5da2fe",
|
||||
600: "#2f81ef",
|
||||
700: "#2780eb",
|
||||
800: "#226fcc",
|
||||
900: "#1b5aa5",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
15
DocSum/depracated/ui/svelte/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "./.svelte-kit/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"checkJs": true,
|
||||
"esModuleInterop": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"resolveJsonModule": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext"
|
||||
}
|
||||
}
|
||||
20
DocSum/depracated/ui/svelte/vite.config.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { sveltekit } from "@sveltejs/kit/vite";
|
||||
import { defineConfig } from "vite";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [sveltekit()],
|
||||
});
|
||||
111
DocSum/microservice/gaudi/README.md
Normal file
@@ -0,0 +1,111 @@
|
||||
# Build MegaService of Document Summarization on Gaudi
|
||||
|
||||
This document outlines the deployment process for a Document Summarization application utilizing the [GenAIComps](https://github.com/opea-project/GenAIComps.git) microservice pipeline on Intel Gaudi server. The steps include Docker image creation, container deployment via Docker Compose, and service execution to integrate microservices such as llm. We will publish the Docker images to Docker Hub, it will simplify the deployment process for this service.
|
||||
|
||||
## 🚀 Build Docker Images
|
||||
|
||||
First of all, you need to build Docker Images locally. This step can be ignored after the Docker images published to Docker hub.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
cd GenAIComps
|
||||
```
|
||||
|
||||
### 1. Pull TGI Gaudi Image
|
||||
|
||||
As TGI Gaudi has been officially published as a Docker image, we simply need to pull it.
|
||||
|
||||
```bash
|
||||
docker pull ghcr.io/huggingface/tgi-gaudi:1.2.1
|
||||
```
|
||||
|
||||
### 2. Build LLM Image
|
||||
|
||||
```bash
|
||||
docker build -t opea/gen-ai-comps:llm-docsum-gaudi-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/llms/docsum/langchain/docker/Dockerfile .
|
||||
```
|
||||
|
||||
### 3. Build MegaService Docker Image
|
||||
|
||||
To construct the Mega Service, we utilize the [GenAIComps](https://github.com/opea-project/GenAIComps.git) microservice pipeline within the `docsum.py` Python script. Build the MegaService Docker image using the command below:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/opea-project/GenAIExamples
|
||||
cd GenAIExamples/DocSum/microservice/gaudi/
|
||||
docker build -t opea/gen-ai-comps:docsum-megaservice-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
|
||||
```
|
||||
|
||||
### 4. Build UI Docker Image
|
||||
|
||||
Construct the frontend Docker image using the command below:
|
||||
|
||||
```bash
|
||||
cd GenAIExamples/DocSum/ui/
|
||||
docker build -t opea/gen-ai-comps:docsum-ui-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f ./docker/Dockerfile .
|
||||
```
|
||||
|
||||
Then run the command `docker images`, you will have the following Docker Images:
|
||||
|
||||
1. `ghcr.io/huggingface/tgi-gaudi:1.2.1`
|
||||
2. `opea/gen-ai-comps:llm-tgi-server`
|
||||
3. `opea/gen-ai-comps:docsum-megaservice-server`
|
||||
4. `opea/gen-ai-comps:docsum-ui-server`
|
||||
|
||||
## 🚀 Start Microservices and MegaService
|
||||
|
||||
### Setup Environment Variables
|
||||
|
||||
Since the `docker_compose.yaml` will consume some environment variables, you need to setup them in advance as below.
|
||||
|
||||
```bash
|
||||
export http_proxy=${your_http_proxy}
|
||||
export https_proxy=${your_http_proxy}
|
||||
export LLM_MODEL_ID="Intel/neural-chat-7b-v3-3"
|
||||
export TGI_LLM_ENDPOINT="http://${your_ip}:8008"
|
||||
export HUGGINGFACEHUB_API_TOKEN=${your_hf_api_token}
|
||||
export MEGA_SERVICE_HOST_IP=${host_ip}
|
||||
export BACKEND_SERVICE_ENDPOINT="http://${host_ip}:8888/v1/docsum"
|
||||
```
|
||||
|
||||
Note: Please replace with `host_ip` with you external IP address, do not use localhost.
|
||||
|
||||
### Start Microservice Docker Containers
|
||||
|
||||
```bash
|
||||
docker compose -f docker_compose.yaml up -d
|
||||
```
|
||||
|
||||
### Validate Microservices
|
||||
|
||||
1. TGI Service
|
||||
|
||||
```bash
|
||||
curl http://${your_ip}:8008/generate \
|
||||
-X POST \
|
||||
-d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":64, "do_sample": true}}' \
|
||||
-H 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
2. LLM Microservice
|
||||
|
||||
```bash
|
||||
curl http://${your_ip}:9000/v1/chat/docsum \
|
||||
-X POST \
|
||||
-d '{"query":"Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' \
|
||||
-H 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
3. MegaService
|
||||
|
||||
```bash
|
||||
curl http://${host_ip}:8888/v1/docsum -H "Content-Type: application/json" -d '{
|
||||
"model": "Intel/neural-chat-7b-v3-3",
|
||||
"messages": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."
|
||||
}'
|
||||
```
|
||||
|
||||
## 🚀 Launch the UI
|
||||
|
||||
Open this URL `http://{host_ip}:5173` in your browser to access the frontend.
|
||||
|
||||

|
||||
41
DocSum/microservice/gaudi/docker/Dockerfile
Normal file
@@ -0,0 +1,41 @@
|
||||
# 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.
|
||||
|
||||
|
||||
FROM langchain/langchain:latest
|
||||
|
||||
RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missing \
|
||||
libgl1-mesa-glx \
|
||||
libjemalloc-dev \
|
||||
vim
|
||||
|
||||
RUN useradd -m -s /bin/bash user && \
|
||||
mkdir -p /home/user && \
|
||||
chown -R user /home/user/
|
||||
|
||||
RUN cd /home/user/ && \
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
|
||||
RUN cd /home/user/GenAIComps && pip install --no-cache-dir --upgrade pip && \
|
||||
pip install -r /home/user/GenAIComps/requirements.txt
|
||||
|
||||
COPY ../docsum.py /home/user/docsum.py
|
||||
|
||||
ENV PYTHONPATH=$PYTHONPATH:/home/user/GenAIComps
|
||||
|
||||
USER user
|
||||
|
||||
WORKDIR /home/user
|
||||
|
||||
ENTRYPOINT ["python", "docsum.py"]
|
||||
75
DocSum/microservice/gaudi/docker_compose.yaml
Normal file
@@ -0,0 +1,75 @@
|
||||
# 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.
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
tgi_service:
|
||||
image: ghcr.io/huggingface/tgi-gaudi:1.2.1
|
||||
container_name: tgi-gaudi-server
|
||||
ports:
|
||||
- "8008:80"
|
||||
environment:
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
TGI_LLM_ENDPOINT: ${TGI_LLM_ENDPOINT}
|
||||
HUGGINGFACEHUB_API_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||
volumes:
|
||||
- "./data:/data"
|
||||
command: --model-id ${LLM_MODEL_ID}
|
||||
llm:
|
||||
image: opea/gen-ai-comps:llm-docsum-gaudi-server
|
||||
container_name: llm-docsum-gaudi-server
|
||||
depends_on:
|
||||
- tgi_service
|
||||
ports:
|
||||
- "9000:9000"
|
||||
ipc: host
|
||||
environment:
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
TGI_LLM_ENDPOINT: ${TGI_LLM_ENDPOINT}
|
||||
HUGGINGFACEHUB_API_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||
restart: unless-stopped
|
||||
docsum-gaudi-backend-server:
|
||||
image: opea/gen-ai-comps:docsum-megaservice-server
|
||||
container_name: docsum-gaudi-backend-server
|
||||
depends_on:
|
||||
- tgi_service
|
||||
- llm
|
||||
ports:
|
||||
- "8888:8888"
|
||||
environment:
|
||||
- https_proxy=${https_proxy}
|
||||
- http_proxy=${http_proxy}
|
||||
- MEGA_SERVICE_HOST_IP=${MEGA_SERVICE_HOST_IP}
|
||||
ipc: host
|
||||
restart: always
|
||||
docsum-gaudi-ui-server:
|
||||
image: opea/gen-ai-comps:docsum-ui-server
|
||||
container_name: docsum-gaudi-ui-server
|
||||
depends_on:
|
||||
- docsum-gaudi-backend-server
|
||||
ports:
|
||||
- "5173:5173"
|
||||
environment:
|
||||
- https_proxy=${https_proxy}
|
||||
- http_proxy=${http_proxy}
|
||||
- DOC_BASE_URL=${BACKEND_SERVICE_ENDPOINT}
|
||||
ipc: host
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
53
DocSum/microservice/gaudi/docsum.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# 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 asyncio
|
||||
import os
|
||||
|
||||
from comps import DocSumGateway, MicroService, ServiceOrchestrator, ServiceType
|
||||
|
||||
SERVICE_HOST_IP = os.getenv("MEGA_SERVICE_HOST_IP", "0.0.0.0")
|
||||
|
||||
|
||||
class DocSumService:
|
||||
def __init__(self, port=8000):
|
||||
self.port = port
|
||||
self.megaservice = ServiceOrchestrator()
|
||||
|
||||
def add_remote_service(self):
|
||||
llm = MicroService(
|
||||
name="llm",
|
||||
host=SERVICE_HOST_IP,
|
||||
port=9000,
|
||||
endpoint="/v1/chat/docsum",
|
||||
use_remote_service=True,
|
||||
service_type=ServiceType.LLM,
|
||||
)
|
||||
self.megaservice.add(llm)
|
||||
self.gateway = DocSumGateway(megaservice=self.megaservice, host="0.0.0.0", port=self.port)
|
||||
|
||||
async def schedule(self):
|
||||
await self.megaservice.schedule(
|
||||
initial_inputs={
|
||||
"text": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."
|
||||
}
|
||||
)
|
||||
result_dict = self.megaservice.result_dict
|
||||
print(result_dict)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
docsum = DocSumService(port=8888)
|
||||
docsum.add_remote_service()
|
||||
asyncio.run(docsum.schedule())
|
||||
114
DocSum/microservice/xeon/README.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# Build Mega Service of Document Summarization on Xeon
|
||||
|
||||
This document outlines the deployment process for a Document Summarization application utilizing the [GenAIComps](https://github.com/opea-project/GenAIComps.git) microservice pipeline on Intel Xeon server. The steps include Docker image creation, container deployment via Docker Compose, and service execution to integrate microservices such as `llm`. We will publish the Docker images to Docker Hub soon, it will simplify the deployment process for this service.
|
||||
|
||||
## 🚀 Apply Xeon Server on AWS
|
||||
|
||||
To apply a Xeon server on AWS, start by creating an AWS account if you don't have one already. Then, head to the [EC2 Console](https://console.aws.amazon.com/ec2/v2/home) to begin the process. Within the EC2 service, select the Amazon EC2 M7i or M7i-flex instance type to leverage the power of 4th Generation Intel Xeon Scalable processors. These instances are optimized for high-performance computing and demanding workloads.
|
||||
|
||||
For detailed information about these instance types, you can refer to this [link](https://aws.amazon.com/ec2/instance-types/m7i/). Once you've chosen the appropriate instance type, proceed with configuring your instance settings, including network configurations, security groups, and storage options.
|
||||
|
||||
After launching your instance, you can connect to it using SSH (for Linux instances) or Remote Desktop Protocol (RDP) (for Windows instances). From there, you'll have full access to your Xeon server, allowing you to install, configure, and manage your applications as needed.
|
||||
|
||||
## 🚀 Build Docker Images
|
||||
|
||||
First of all, you need to build Docker Images locally and install the python package of it.
|
||||
|
||||
```bash
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
cd GenAIComps
|
||||
```
|
||||
|
||||
### 1. Build LLM Image
|
||||
|
||||
```bash
|
||||
docker build -t opea/gen-ai-comps:llm-docsum-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/llms/docsum/langchain/docker/Dockerfile .
|
||||
```
|
||||
|
||||
Then run the command `docker images`, you will have the following four Docker Images:
|
||||
|
||||
### 2. Build MegaService Docker Image
|
||||
|
||||
To construct the Mega Service, we utilize the [GenAIComps](https://github.com/opea-project/GenAIComps.git) microservice pipeline within the `docsum.py` Python script. Build MegaService Docker image via below command:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/opea-project/GenAIExamples
|
||||
cd GenAIExamples/DocSum/microservice/xeon/
|
||||
docker build -t opea/gen-ai-comps:docsum-megaservice-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
|
||||
```
|
||||
|
||||
### 3. Build UI Docker Image
|
||||
|
||||
Build frontend Docker image via below command:
|
||||
|
||||
```bash
|
||||
cd GenAIExamples/DocSum/ui/
|
||||
docker build -t opea/gen-ai-comps:docsum-ui-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f ./docker/Dockerfile .
|
||||
```
|
||||
|
||||
Then run the command `docker images`, you will have the following Docker Images:
|
||||
|
||||
1. `opea/gen-ai-comps:llm-docsum-server`
|
||||
2. `opea/gen-ai-comps:docsum-megaservice-server`
|
||||
3. `opea/gen-ai-comps:docsum-ui-server`
|
||||
|
||||
## 🚀 Start Microservices and MegaService
|
||||
|
||||
### Setup Environment Variables
|
||||
|
||||
Since the `docker_compose.yaml` will consume some environment variables, you need to setup them in advance as below.
|
||||
|
||||
```bash
|
||||
export http_proxy=${your_http_proxy}
|
||||
export https_proxy=${your_http_proxy}
|
||||
export LLM_MODEL_ID="Intel/neural-chat-7b-v3-3"
|
||||
export TGI_LLM_ENDPOINT="http://${your_ip}:8008"
|
||||
export HUGGINGFACEHUB_API_TOKEN=${your_hf_api_token}
|
||||
export MEGA_SERVICE_HOST_IP=${host_ip}
|
||||
export BACKEND_SERVICE_ENDPOINT="http://${host_ip}:8888/v1/docsum"
|
||||
```
|
||||
|
||||
Note: Please replace with `host_ip` with you external IP address, do not use localhost.
|
||||
|
||||
### Start Microservice Docker Containers
|
||||
|
||||
```bash
|
||||
docker compose -f docker_compose.yaml up -d
|
||||
```
|
||||
|
||||
### Validate Microservices
|
||||
|
||||
1. TGI Service
|
||||
|
||||
```bash
|
||||
curl http://${your_ip}:8008/generate \
|
||||
-X POST \
|
||||
-d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":17, "do_sample": true}}' \
|
||||
-H 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
2. LLM Microservice
|
||||
|
||||
```bash
|
||||
curl http://${your_ip}:9000/v1/chat/docsum \
|
||||
-X POST \
|
||||
-d '{"query":"Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' \
|
||||
-H 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
3. MegaService
|
||||
|
||||
```bash
|
||||
curl http://${host_ip}:8888/v1/docsum -H "Content-Type: application/json" -d '{
|
||||
"model": "Intel/neural-chat-7b-v3-3",
|
||||
"messages": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."
|
||||
}'
|
||||
```
|
||||
|
||||
Following the validation of all aforementioned microservices, we are now prepared to construct a mega-service.
|
||||
|
||||
## 🚀 Launch the UI
|
||||
|
||||
Open this URL `http://{host_ip}:5173` in your browser to access the frontend.
|
||||
|
||||

|
||||
41
DocSum/microservice/xeon/docker/Dockerfile
Normal file
@@ -0,0 +1,41 @@
|
||||
# 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.
|
||||
|
||||
|
||||
FROM langchain/langchain:latest
|
||||
|
||||
RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missing \
|
||||
libgl1-mesa-glx \
|
||||
libjemalloc-dev \
|
||||
vim
|
||||
|
||||
RUN useradd -m -s /bin/bash user && \
|
||||
mkdir -p /home/user && \
|
||||
chown -R user /home/user/
|
||||
|
||||
RUN cd /home/user/ && \
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
|
||||
RUN cd /home/user/GenAIComps && pip install --no-cache-dir --upgrade pip && \
|
||||
pip install -r /home/user/GenAIComps/requirements.txt
|
||||
|
||||
COPY ../docsum.py /home/user/docsum.py
|
||||
|
||||
ENV PYTHONPATH=$PYTHONPATH:/home/user/GenAIComps
|
||||
|
||||
USER user
|
||||
|
||||
WORKDIR /home/user
|
||||
|
||||
ENTRYPOINT ["python", "docsum.py"]
|
||||
76
DocSum/microservice/xeon/docker_compose.yaml
Normal file
@@ -0,0 +1,76 @@
|
||||
# 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.
|
||||
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
tgi_service:
|
||||
image: ghcr.io/huggingface/text-generation-inference:1.4
|
||||
container_name: tgi_service
|
||||
ports:
|
||||
- "8008:80"
|
||||
environment:
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
TGI_LLM_ENDPOINT: ${TGI_LLM_ENDPOINT}
|
||||
HUGGINGFACEHUB_API_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||
volumes:
|
||||
- "./data:/data"
|
||||
shm_size: 1g
|
||||
command: --model-id ${LLM_MODEL_ID}
|
||||
llm:
|
||||
image: opea/gen-ai-comps:llm-docsum-server
|
||||
container_name: llm-docsum-server
|
||||
depends_on:
|
||||
- tgi_service
|
||||
ports:
|
||||
- "9000:9000"
|
||||
ipc: host
|
||||
environment:
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
TGI_LLM_ENDPOINT: ${TGI_LLM_ENDPOINT}
|
||||
HUGGINGFACEHUB_API_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||
restart: unless-stopped
|
||||
docsum-xeon-backend-server:
|
||||
image: opea/gen-ai-comps:docsum-megaservice-server
|
||||
container_name: docsum-xeon-backend-server
|
||||
depends_on:
|
||||
- tgi_service
|
||||
- llm
|
||||
ports:
|
||||
- "8888:8888"
|
||||
environment:
|
||||
- https_proxy=${https_proxy}
|
||||
- http_proxy=${http_proxy}
|
||||
- MEGA_SERVICE_HOST_IP=${MEGA_SERVICE_HOST_IP}
|
||||
ipc: host
|
||||
restart: always
|
||||
docsum-xeon-ui-server:
|
||||
image: opea/gen-ai-comps:docsum-ui-server
|
||||
container_name: docsum-xeon-ui-server
|
||||
depends_on:
|
||||
- docsum-xeon-backend-server
|
||||
ports:
|
||||
- "5173:5173"
|
||||
environment:
|
||||
- https_proxy=${https_proxy}
|
||||
- http_proxy=${http_proxy}
|
||||
- DOC_BASE_URL=${BACKEND_SERVICE_ENDPOINT}
|
||||
ipc: host
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
53
DocSum/microservice/xeon/docsum.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# 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 asyncio
|
||||
import os
|
||||
|
||||
from comps import DocSumGateway, MicroService, ServiceOrchestrator, ServiceType
|
||||
|
||||
SERVICE_HOST_IP = os.getenv("MEGA_SERVICE_HOST_IP", "0.0.0.0")
|
||||
|
||||
|
||||
class DocSumService:
|
||||
def __init__(self, port=8000):
|
||||
self.port = port
|
||||
self.megaservice = ServiceOrchestrator()
|
||||
|
||||
def add_remote_service(self):
|
||||
llm = MicroService(
|
||||
name="llm",
|
||||
host=SERVICE_HOST_IP,
|
||||
port=9000,
|
||||
endpoint="/v1/chat/docsum",
|
||||
use_remote_service=True,
|
||||
service_type=ServiceType.LLM,
|
||||
)
|
||||
self.megaservice.add(llm)
|
||||
self.gateway = DocSumGateway(megaservice=self.megaservice, host="0.0.0.0", port=self.port)
|
||||
|
||||
async def schedule(self):
|
||||
await self.megaservice.schedule(
|
||||
initial_inputs={
|
||||
"text": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."
|
||||
}
|
||||
)
|
||||
result_dict = self.megaservice.result_dict
|
||||
print(result_dict)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
docsum = DocSumService(port=8888)
|
||||
docsum.add_remote_service()
|
||||
asyncio.run(docsum.schedule())
|
||||
124
DocSum/tests/test_docsum_on_gaudi.sh
Normal file
@@ -0,0 +1,124 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -x
|
||||
|
||||
WORKPATH=$(dirname "$PWD")
|
||||
LOG_PATH="$WORKPATH/tests"
|
||||
ip_name=$(echo $(hostname) | tr '[a-z]-' '[A-Z]_')_$(echo 'IP')
|
||||
ip_address=$(eval echo '$'$ip_name)
|
||||
|
||||
function build_docker_images() {
|
||||
cd $WORKPATH
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
cd GenAIComps
|
||||
|
||||
docker build -t opea/gen-ai-comps:llm-docsum-gaudi-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/llms/docsum/langchain/docker/Dockerfile .
|
||||
|
||||
docker pull ghcr.io/huggingface/tgi-gaudi:1.2.1
|
||||
|
||||
cd $WORKPATH/microservice/gaudi
|
||||
docker build --no-cache -t opea/gen-ai-comps:docsum-megaservice-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
|
||||
|
||||
cd $WORKPATH/ui
|
||||
docker build --no-cache -t opea/gen-ai-comps:docsum-ui-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
|
||||
|
||||
docker images
|
||||
}
|
||||
|
||||
function start_services() {
|
||||
cd $WORKPATH/microservice/gaudi
|
||||
|
||||
export LLM_MODEL_ID="Intel/neural-chat-7b-v3-3"
|
||||
export TGI_LLM_ENDPOINT="http://${ip_address}:8008"
|
||||
export HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN}
|
||||
export MEGA_SERVICE_HOST_IP=${ip_address}
|
||||
export BACKEND_SERVICE_ENDPOINT="http://${ip_address}:8888/v1/docsum"
|
||||
|
||||
# Start Docker Containers
|
||||
# TODO: Replace the container name with a test-specific name
|
||||
docker compose -f docker_compose.yaml up -d
|
||||
|
||||
sleep 2m # Waits 2 minutes
|
||||
}
|
||||
|
||||
function validate_microservices() {
|
||||
# Check if the microservices are running correctly.
|
||||
# TODO: Any results check required??
|
||||
curl http://${ip_address}:8008/generate \
|
||||
-X POST \
|
||||
-d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":64, "do_sample": true}}' \
|
||||
-H 'Content-Type: application/json' > ${LOG_PATH}/generate.log
|
||||
exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
echo "Microservice failed, please check the logs in artifacts!"
|
||||
docker logs tgi-gaudi-server >> ${LOG_PATH}/generate.log
|
||||
exit 1
|
||||
fi
|
||||
sleep 5s
|
||||
|
||||
curl http://${ip_address}:9000/v1/chat/docsum \
|
||||
-X POST \
|
||||
-d '{"query":"Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' \
|
||||
-H 'Content-Type: application/json' > ${LOG_PATH}/completions.log
|
||||
exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
echo "Microservice failed, please check the logs in artifacts!"
|
||||
docker logs docsum-gaudi-backend-server >> ${LOG_PATH}/completions.log
|
||||
exit 1
|
||||
fi
|
||||
sleep 5s
|
||||
}
|
||||
|
||||
function validate_megaservice() {
|
||||
# Curl the Mega Service
|
||||
curl http://${ip_address}:8888/v1/docsum -H "Content-Type: application/json" -d '{
|
||||
"model": "Intel/neural-chat-7b-v3-3",
|
||||
"messages": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' > ${LOG_PATH}/curl_megaservice.log
|
||||
|
||||
echo "Checking response results, make sure the output is reasonable. "
|
||||
local status=false
|
||||
if [[ -f $LOG_PATH/curl_megaservice.log ]] && \
|
||||
[[ $(grep -c "versatile toolkit" $LOG_PATH/curl_megaservice.log) != 0 ]] && \
|
||||
[[ $(grep -c "offering" $LOG_PATH/curl_megaservice.log) != 0 ]] && \
|
||||
[[ $(grep -c "extraction" $LOG_PATH/curl_megaservice.log) != 0 ]]; then
|
||||
status=true
|
||||
fi
|
||||
|
||||
if [ $status == false ]; then
|
||||
echo "Response check failed, please check the logs in artifacts!"
|
||||
exit 1
|
||||
else
|
||||
echo "Response check succeed!"
|
||||
fi
|
||||
|
||||
echo "Checking response format, make sure the output format is acceptable for UI."
|
||||
# TODO
|
||||
}
|
||||
|
||||
function stop_docker() {
|
||||
cd $WORKPATH/microservice/gaudi
|
||||
container_list=$(cat docker_compose.yaml | grep container_name | cut -d':' -f2)
|
||||
for container_name in $container_list; do
|
||||
cid=$(docker ps -aq --filter "name=$container_name")
|
||||
if [[ ! -z "$cid" ]]; then docker stop $cid && docker rm $cid && sleep 1s; fi
|
||||
done
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
||||
stop_docker
|
||||
|
||||
build_docker_images
|
||||
start_services
|
||||
|
||||
validate_microservices
|
||||
validate_megaservice
|
||||
|
||||
stop_docker
|
||||
echo y | docker system prune
|
||||
|
||||
}
|
||||
|
||||
main
|
||||
123
DocSum/tests/test_docsum_on_xeon.sh
Normal file
@@ -0,0 +1,123 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -x
|
||||
|
||||
WORKPATH=$(dirname "$PWD")
|
||||
LOG_PATH="$WORKPATH/tests"
|
||||
ip_name=$(echo $(hostname) | tr '[a-z]-' '[A-Z]_')_$(echo 'IP')
|
||||
ip_address=$(eval echo '$'$ip_name)
|
||||
|
||||
function build_docker_images() {
|
||||
cd $WORKPATH
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
cd GenAIComps
|
||||
|
||||
docker build -t opea/gen-ai-comps:llm-docsum-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/llms/docsum/langchain/docker/Dockerfile .
|
||||
|
||||
cd $WORKPATH/microservice/xeon
|
||||
docker build --no-cache -t opea/gen-ai-comps:docsum-megaservice-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
|
||||
|
||||
cd $WORKPATH/ui
|
||||
docker build --no-cache -t opea/gen-ai-comps:docsum-ui-server --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f docker/Dockerfile .
|
||||
|
||||
docker images
|
||||
}
|
||||
|
||||
function start_services() {
|
||||
cd $WORKPATH/microservice/xeon
|
||||
|
||||
export LLM_MODEL_ID="Intel/neural-chat-7b-v3-3"
|
||||
export TGI_LLM_ENDPOINT="http://${ip_address}:8008"
|
||||
export HUGGINGFACEHUB_API_TOKEN=${HUGGINGFACEHUB_API_TOKEN}
|
||||
export MEGA_SERVICE_HOST_IP=${ip_address}
|
||||
export BACKEND_SERVICE_ENDPOINT="http://${ip_address}:8888/v1/docsum"
|
||||
|
||||
# Start Docker Containers
|
||||
# TODO: Replace the container name with a test-specific name
|
||||
docker compose -f docker_compose.yaml up -d
|
||||
|
||||
sleep 2m # Waits 2 minutes
|
||||
}
|
||||
|
||||
function validate_microservices() {
|
||||
# Check if the microservices are running correctly.
|
||||
# TODO: Any results check required??
|
||||
curl http://${ip_address}:8008/generate \
|
||||
-X POST \
|
||||
-d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":17, "do_sample": true}}' \
|
||||
-H 'Content-Type: application/json' > ${LOG_PATH}/generate.log
|
||||
exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
echo "Microservice failed, please check the logs in artifacts!"
|
||||
docker logs tgi_service >> ${LOG_PATH}/generate.log
|
||||
exit 1
|
||||
fi
|
||||
sleep 5s
|
||||
|
||||
curl http://${ip_address}:9000/v1/chat/docsum \
|
||||
-X POST \
|
||||
-d '{"query":"Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' \
|
||||
-H 'Content-Type: application/json' > ${LOG_PATH}/completions.log
|
||||
exit_code=$?
|
||||
if [ $exit_code -ne 0 ]; then
|
||||
echo "Microservice failed, please check the logs in artifacts!"
|
||||
docker logs llm-docsum-server >> ${LOG_PATH}/completions.log
|
||||
exit 1
|
||||
fi
|
||||
sleep 5s
|
||||
}
|
||||
|
||||
function validate_megaservice() {
|
||||
# Curl the Mega Service
|
||||
curl http://${ip_address}:8888/v1/docsum -H "Content-Type: application/json" -d '{
|
||||
"model": "Intel/neural-chat-7b-v3-3",
|
||||
"messages": "Text Embeddings Inference (TEI) is a toolkit for deploying and serving open source text embeddings and sequence classification models. TEI enables high-performance extraction for the most popular models, including FlagEmbedding, Ember, GTE and E5."}' > ${LOG_PATH}/curl_megaservice.log
|
||||
|
||||
echo "Checking response results, make sure the output is reasonable. "
|
||||
local status=false
|
||||
if [[ -f $LOG_PATH/curl_megaservice.log ]] && \
|
||||
[[ $(grep -c " flexible" $LOG_PATH/curl_megaservice.log) != 0 ]] && \
|
||||
[[ $(grep -c " tool" $LOG_PATH/curl_megaservice.log) != 0 ]] && \
|
||||
[[ $(grep -c "kit" $LOG_PATH/curl_megaservice.log) != 0 ]]; then
|
||||
status=true
|
||||
fi
|
||||
|
||||
if [ $status == false ]; then
|
||||
echo "Response check failed, please check the logs in artifacts!"
|
||||
exit 1
|
||||
else
|
||||
echo "Response check succeed!"
|
||||
fi
|
||||
|
||||
echo "Checking response format, make sure the output format is acceptable for UI."
|
||||
# TODO
|
||||
|
||||
}
|
||||
|
||||
function stop_docker() {
|
||||
cd $WORKPATH/microservice/xeon
|
||||
container_list=$(cat docker_compose.yaml | grep container_name | cut -d':' -f2)
|
||||
for container_name in $container_list; do
|
||||
cid=$(docker ps -aq --filter "name=$container_name")
|
||||
if [[ ! -z "$cid" ]]; then docker stop $cid && docker rm $cid && sleep 1s; fi
|
||||
done
|
||||
}
|
||||
|
||||
function main() {
|
||||
|
||||
stop_docker
|
||||
|
||||
build_docker_images
|
||||
start_services
|
||||
|
||||
validate_microservices
|
||||
validate_megaservice
|
||||
|
||||
stop_docker
|
||||
echo y | docker system prune
|
||||
|
||||
}
|
||||
|
||||
main
|
||||
20
DocSum/ui/docker/Dockerfile
Normal file
@@ -0,0 +1,20 @@
|
||||
# Use node 20.11.1 as the base image
|
||||
FROM node:20.11.1
|
||||
|
||||
# Update package manager and install Git
|
||||
RUN apt-get update -y && apt-get install -y git
|
||||
|
||||
# Clone the front-end code repository
|
||||
RUN git clone https://github.com/opea-project/GenAIExamples.git /home/user/GenAIExamples
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /home/user/GenAIExamples/DocSum/ui/svelte
|
||||
|
||||
# Install front-end dependencies
|
||||
RUN npm install
|
||||
|
||||
# Expose the port of the front-end application
|
||||
EXPOSE 5173
|
||||
|
||||
# Run the front-end application
|
||||
CMD ["npm", "run", "dev", "--", "--host=0.0.0.0"]
|
||||
10
DocSum/ui/svelte/.editorconfig
Normal file
@@ -0,0 +1,10 @@
|
||||
[*]
|
||||
indent_style = tab
|
||||
|
||||
[package.json]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
|
||||
[*.md]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
@@ -1 +1,6 @@
|
||||
BASIC_URL = 'http://x.x.x.x:yyyy'
|
||||
CHAT_BASE_URL = 'http://x.x.x.x'
|
||||
|
||||
UPLOAD_FILE_BASE_URL = 'http://x.x.x.x'
|
||||
|
||||
PASTE_LINK_BASE_URL = 'http://x.x.x.x'
|
||||
|
||||
|
||||
13
DocSum/ui/svelte/.eslintignore
Normal file
@@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
34
DocSum/ui/svelte/.eslintrc.cjs
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: "@typescript-eslint/parser",
|
||||
extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
|
||||
plugins: ["svelte3", "@typescript-eslint", "neverthrow"],
|
||||
ignorePatterns: ["*.cjs"],
|
||||
overrides: [{ files: ["*.svelte"], processor: "svelte3/svelte3" }],
|
||||
settings: {
|
||||
"svelte3/typescript": () => require("typescript"),
|
||||
},
|
||||
parserOptions: {
|
||||
sourceType: "module",
|
||||
ecmaVersion: 2020,
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2017: true,
|
||||
node: true,
|
||||
},
|
||||
};
|
||||
13
DocSum/ui/svelte/.prettierignore
Normal file
@@ -0,0 +1,13 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
/.svelte-kit
|
||||
/package
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Ignore files for PNPM, NPM and YARN
|
||||
pnpm-lock.yaml
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
13
DocSum/ui/svelte/.prettierrc
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"pluginSearchDirs": [
|
||||
"."
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": "*.svelte",
|
||||
"options": {
|
||||
"parser": "svelte"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,19 +1,21 @@
|
||||
<h1 align="center" id="title">Doc Summary</h1>
|
||||
<h1 align="center" id="title"> ChatQnA Customized UI</h1>
|
||||
|
||||
### 📸 Project Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
<h2>🧐 Features</h2>
|
||||
|
||||
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.
|
||||
- Start a Text Chat:Initiate a text chat with the ability to input written conversations, where the dialogue content can also be customized based on uploaded files.
|
||||
- Upload File: The choice between uploading locally or copying a remote link. Chat according to uploaded knowledge base.
|
||||
- Clear: Clear the record of the current dialog box without retaining the contents of the dialog box.
|
||||
- Chat history: Historical chat records can still be retained after refreshing, making it easier for users to view the context.
|
||||
- Scroll to Bottom / Top: The chat automatically slides to the bottom. Users can also click the top icon to slide to the top of the chat record.
|
||||
- End to End Time: Shows the time spent on the current conversation.
|
||||
|
||||
<h2>🛠️ Get it Running:</h2>
|
||||
|
||||
@@ -23,7 +25,7 @@ Here're some of the project's features:
|
||||
|
||||
3. Modify the required .env variables.
|
||||
```
|
||||
BASIC_URL = ''
|
||||
DOC_BASE_URL = ''
|
||||
```
|
||||
4. Execute `npm install` to install the corresponding dependencies.
|
||||
|
||||
|
||||
@@ -1,53 +1,60 @@
|
||||
{
|
||||
"name": "doc-summary",
|
||||
"name": "sveltekit-auth-example",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build && npm run package",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"package": "svelte-kit sync && svelte-package && publint",
|
||||
"prepublishOnly": "npm run package",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
|
||||
},
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
"svelte": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"!dist/**/*.test.*",
|
||||
"!dist/**/*.spec.*"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"svelte": "^4.0.0"
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "^3.0.0",
|
||||
"@sveltejs/kit": "^2.0.0",
|
||||
"@sveltejs/package": "^2.0.0",
|
||||
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
||||
"autoprefixer": "^10.4.16",
|
||||
"flowbite": "^2.3.0",
|
||||
"flowbite-svelte": "^0.38.5",
|
||||
"flowbite-svelte-icons": "^1.4.0",
|
||||
"postcss": "^8.4.32",
|
||||
"postcss-load-config": "^5.0.2",
|
||||
"publint": "^0.1.9",
|
||||
"svelte": "^4.2.7",
|
||||
"svelte-check": "^3.6.0",
|
||||
"tailwindcss": "^3.3.6",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^5.0.11"
|
||||
"@playwright/test": "^1.33.0",
|
||||
"@fortawesome/free-solid-svg-icons": "6.2.0",
|
||||
"@sveltejs/adapter-auto": "1.0.0-next.75",
|
||||
"@sveltejs/kit": "^1.30.4",
|
||||
"@tailwindcss/typography": "0.5.7",
|
||||
"@types/debug": "4.1.7",
|
||||
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
||||
"@typescript-eslint/parser": "^5.27.0",
|
||||
"autoprefixer": "^10.4.7",
|
||||
"daisyui": "3.5.1",
|
||||
"date-picker-svelte": "^2.6.0",
|
||||
"debug": "4.3.4",
|
||||
"eslint": "^8.16.0",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-neverthrow": "1.1.4",
|
||||
"eslint-plugin-svelte3": "^4.0.0",
|
||||
"postcss": "^8.4.31",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"postcss-preset-env": "^8.3.2",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.7.0",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"svelte": "^3.59.1",
|
||||
"svelte-check": "^2.7.1",
|
||||
"svelte-fa": "3.0.3",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"tailwindcss": "^3.1.5",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.7.4",
|
||||
"vite": "^4.5.2"
|
||||
},
|
||||
"svelte": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"date-fns": "^2.30.0",
|
||||
"driver.js": "^1.3.0",
|
||||
"flowbite-svelte": "^0.38.5",
|
||||
"flowbite-svelte-icons": "^1.4.0",
|
||||
"fuse.js": "^6.6.2",
|
||||
"lodash": "^4.17.21",
|
||||
"ramda": "^0.29.0",
|
||||
"sse.js": "^0.6.1",
|
||||
"svelte-notifications": "^0.9.98"
|
||||
"svelte-notifications": "^0.9.98",
|
||||
"playwright": "^1.44.0",
|
||||
"svrollbar": "^0.12.0"
|
||||
}
|
||||
}
|
||||
|
||||
83
DocSum/ui/svelte/playwright.config.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
// Copyright (C) 2024 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import { defineConfig, devices } from "@playwright/test";
|
||||
|
||||
/**
|
||||
* Read environment variables from file.
|
||||
* https://github.com/motdotla/dotenv
|
||||
*/
|
||||
// require('dotenv').config();
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
testDir: "./tests",
|
||||
/* Maximum time one test can run for. */
|
||||
timeout: 30 * 1000,
|
||||
expect: {
|
||||
/**
|
||||
* Maximum time expect() should wait for the condition to be met.
|
||||
* For example in `await expect(locator).toHaveText();`
|
||||
*/
|
||||
timeout: 5000,
|
||||
},
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.CI,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.CI ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
reporter: [["html", { open: "never" }]],
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
|
||||
actionTimeout: 0,
|
||||
/* Base URL to use in actions like `await page.goto('/')`. */
|
||||
baseURL: "http://localhost:5173",
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: "on-first-retry",
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: "chromium",
|
||||
use: { ...devices["Desktop Chrome"] },
|
||||
},
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: { ...devices['Pixel 5'] },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: { ...devices['iPhone 12'] },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: { channel: 'msedge' },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: { channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Folder for test artifacts such as screenshots, videos, traces, etc. */
|
||||
// outputDir: 'test-results/',
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
// webServer: {
|
||||
// command: 'npm run start',
|
||||
// port: 3000,
|
||||
// },
|
||||
});
|
||||
16
DocSum/ui/svelte/src/app.d.ts
vendored
@@ -12,16 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// See https://kit.svelte.dev/docs/types#app
|
||||
// for information about these interfaces
|
||||
declare global {
|
||||
namespace App {
|
||||
// interface Error {}
|
||||
// interface Locals {}
|
||||
// interface PageData {}
|
||||
// interface PageState {}
|
||||
// interface Platform {}
|
||||
// See: https://kit.svelte.dev/docs/types#app
|
||||
// import { Result} from "neverthrow";
|
||||
interface Window {
|
||||
deviceType: string;
|
||||
}
|
||||
}
|
||||
|
||||
export {};
|
||||
|
||||
@@ -19,10 +19,10 @@
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div>%sveltekit.body%</div>
|
||||
<body>
|
||||
<div class="h-full w-full">%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
86
DocSum/ui/svelte/src/app.postcss
Normal file
@@ -0,0 +1,86 @@
|
||||
/* Write your global styles here, in PostCSS syntax */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.btn {
|
||||
@apply flex-nowrap;
|
||||
}
|
||||
a.btn {
|
||||
@apply no-underline;
|
||||
}
|
||||
.input {
|
||||
@apply text-base;
|
||||
}
|
||||
|
||||
.bg-dark-blue {
|
||||
background-color: #004a86;
|
||||
}
|
||||
|
||||
.bg-light-blue {
|
||||
background-color: #0068b5;
|
||||
}
|
||||
|
||||
.bg-turquoise {
|
||||
background-color: #00a3f6;
|
||||
}
|
||||
|
||||
.bg-header {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.bg-button {
|
||||
background-color: #0068b5;
|
||||
}
|
||||
|
||||
.bg-title {
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
.text-header {
|
||||
color: #0068b5;
|
||||
}
|
||||
|
||||
.text-button {
|
||||
color: #252e47;
|
||||
}
|
||||
|
||||
.text-title-color {
|
||||
color: rgb(38,38,38);
|
||||
}
|
||||
|
||||
.font-intel {
|
||||
font-family: "intel-clear","tahoma",Helvetica,"helvetica",Arial,sans-serif;
|
||||
}
|
||||
|
||||
.font-title-intel {
|
||||
font-family: "intel-one","intel-clear",Helvetica,Arial,sans-serif;
|
||||
}
|
||||
|
||||
.bg-footer {
|
||||
background-color: #e7e7e7;
|
||||
}
|
||||
|
||||
.bg-light-green {
|
||||
background-color: #d7f3a1;
|
||||
}
|
||||
|
||||
.bg-purple {
|
||||
background-color: #653171;
|
||||
}
|
||||
|
||||
.bg-dark-blue {
|
||||
background-color: #224678;
|
||||
}
|
||||
|
||||
.border-input-color {
|
||||
border-color: #605e5c;
|
||||
}
|
||||
|
||||
.w-12\/12 {
|
||||
width: 100%
|
||||
}
|
||||
30
DocSum/ui/svelte/src/lib/assets/avatar/svelte/Delete.svelte
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
let dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<svg
|
||||
class="absolute top-0 right-0 hover:opacity-70"
|
||||
on:click={() => {
|
||||
dispatch('DeleteAvatar') }}
|
||||
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="20" height="20">
|
||||
<path d="M512 832c-176.448 0-320-143.552-320-320S335.552 192 512 192s320 143.552 320 320-143.552 320-320 320m0-704C300.256 128 128 300.256 128 512s172.256 384 384 384 384-172.256 384-384S723.744 128 512 128" fill="#bbbbbb"></path><path d="M649.824 361.376a31.968 31.968 0 0 0-45.248 0L505.6 460.352l-98.976-98.976a31.968 31.968 0 1 0-45.248 45.248l98.976 98.976-98.976 98.976a32 32 0 0 0 45.248 45.248l98.976-98.976 98.976 98.976a31.904 31.904 0 0 0 45.248 0 31.968 31.968 0 0 0 0-45.248L550.848 505.6l98.976-98.976a31.968 31.968 0 0 0 0-45.248" fill="#bbbbbb"></path>
|
||||
</svg>
|
||||
44
DocSum/ui/svelte/src/lib/assets/chat/svelte/Assistant.svelte
Normal file
@@ -0,0 +1,44 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- <svg
|
||||
width="35"
|
||||
height="35"
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clip-path="url(#clip0_16_93)">
|
||||
<rect x="0.5" y="0.238312" width="47" height="47" fill="#0068B5" />
|
||||
<path
|
||||
d="M39.51 0.238312H8.49C4.0955 0.238312 0.5 3.83381 0.5 8.22831V39.2483C0.5 43.6428 4.0955 47.2383 8.49 47.2383H39.51C43.9045 47.2383 47.5 43.6428 47.5 39.2483V8.22831C47.5 3.83381 43.9045 0.238312 39.51 0.238312ZM44.915 39.2483C44.915 42.2328 42.4945 44.6533 39.51 44.6533H8.49C5.5055 44.6533 3.085 42.2328 3.085 39.2483V8.22831C3.085 5.24381 5.5055 2.82331 8.49 2.82331H39.51C42.4945 2.82331 44.915 5.24381 44.915 8.22831V39.2483Z"
|
||||
fill="#0068B5"
|
||||
/>
|
||||
<path
|
||||
d="M9.52393 21.3178H11.7094L11.7094 29.3548H9.52393V21.3178ZM20.3574 22.2108C20.1694 21.9523 19.8874 21.7408 19.4879 21.5763C19.1119 21.4118 18.6889 21.3178 18.2424 21.3178C17.2084 21.3178 16.3389 21.7643 15.6574 22.6338V21.4823H13.7304V29.3078H15.7984V25.7593C15.7984 24.8898 15.8454 24.2788 15.9629 23.9498C16.0569 23.6208 16.2684 23.3623 16.5504 23.1743C16.8324 22.9863 17.1614 22.8688 17.5139 22.8688C17.7959 22.8688 18.0309 22.9393 18.2424 23.0803C18.4304 23.2213 18.5949 23.4093 18.6654 23.6678C18.7594 23.9263 18.8064 24.4668 18.8064 25.3128V29.3078H20.8744V24.4433C20.8744 23.8323 20.8274 23.3858 20.7569 23.0568C20.6864 22.7513 20.5689 22.4693 20.3574 22.2108ZM25.7389 27.8038C25.5979 27.8038 25.4804 27.7803 25.3864 27.7098C25.2924 27.6393 25.2219 27.5453 25.1984 27.4513C25.1749 27.3573 25.1514 26.9813 25.1514 26.3233V23.1508H26.5614V21.5058H25.1514V18.7563L23.0834 19.9548V21.5058V23.1508V26.5583C23.0834 27.2868 23.1069 27.7803 23.1539 28.0153C23.2009 28.3443 23.2949 28.6263 23.4359 28.8143C23.5769 29.0023 23.7884 29.1668 24.0939 29.3078C24.3994 29.4253 24.7284 29.4958 25.1044 29.4958C25.7154 29.4958 26.2559 29.4018 26.7494 29.1903L26.5614 27.5923C26.2089 27.7333 25.9269 27.8038 25.7389 27.8038ZM33.7524 22.4928C33.0709 21.7173 32.1544 21.3413 31.0029 21.3413C29.9689 21.3413 29.0994 21.7173 28.4414 22.4458C27.7599 23.1743 27.4309 24.1848 27.4309 25.5008C27.4309 26.5818 27.6894 27.4748 28.2064 28.2033C28.8644 29.0963 29.8749 29.5428 31.2379 29.5428C32.1074 29.5428 32.8124 29.3548 33.3764 28.9553C33.9404 28.5558 34.3634 27.9918 34.6219 27.2163L32.5539 26.8638C32.4364 27.2633 32.2719 27.5453 32.0604 27.7098C31.8489 27.8743 31.5669 27.9683 31.2379 27.9683C30.7679 27.9683 30.3684 27.8038 30.0394 27.4513C29.7104 27.0988 29.5459 26.6288 29.5459 26.0178H34.7394C34.7394 24.4433 34.4339 23.2448 33.7524 22.4928ZM29.5694 24.7488C29.5694 24.1848 29.7104 23.7383 29.9924 23.4093C30.2979 23.0803 30.6504 22.9158 31.1204 22.9158C31.5434 22.9158 31.8959 23.0803 32.2014 23.3858C32.5069 23.6913 32.6479 24.1613 32.6714 24.7488H29.5694ZM36.4079 18.5448H38.4759V29.3548H36.4079V18.5448Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M9.52393 18.5448H11.7094L11.7094 20.5654H9.52393V18.5448ZM39.2058 53.1889C59.7131 70.5741 37.9465 53.1367 37.547 52.9722C60.5267 71.228 41.5876 53.1889 41.1411 53.1889C40.1071 53.1889 54.2638 57.2959 53.5823 58.1654L44.3775 54.0099L42.8 56.0803L44.9335 56.0763L43.617 55.1029L49.2888 57.4321C49.2888 56.5626 69.0838 68.5409 41.665 52.9722C67.9574 69.2353 48.7539 58.3534 49.0359 58.1654C49.3179 57.9774 72.2331 77.3305 48.0529 59.0448C73.8431 77.373 40.6532 52.2185 40.8647 52.3595C64.5928 69.3279 66.2469 69.734 44.0477 53.3531C68.4587 70.8049 45.1808 54.42 45.1808 55.266L49.6436 57.6191L50.8176 56.2254L46.645 54.7317C46.645 54.1207 47.0599 55.184 46.9894 54.855C46.9189 54.5495 63.0924 72.6928 39.2058 53.1889ZM45.3834 56.0442C45.2424 56.0442 60.49 64.1373 43.0764 53.1889C59.6606 67.1938 58.0346 62.1756 40.8647 50.7007C58.8678 64.6804 43.7296 53.3942 43.7296 52.7362L43.617 55.1029L43.3529 52.3595L44.7353 53.7418L43.0764 53.1889L44.244 54.855L46.1176 55.6771L42.8 57.336L45.5647 53.1889L41.9705 49.5948L46.1176 55.1029L46.3941 55.6771C46.3941 56.4056 44.3403 54.3363 44.3873 54.5713C65.2775 66.4664 68.0297 70.4029 45.348 56.6803C69.965 73.7705 43.9793 55.5361 44.2848 55.6771C44.5903 55.7946 60.4832 66.2088 41.9705 53.7418C42.5815 53.7418 44.8545 53.1837 45.348 52.9722L43.7511 52.3595C43.3986 52.5005 45.5714 56.0442 45.3834 56.0442ZM44.0342 56.5108C43.3527 55.7353 45.3338 56.783 44.1823 56.783C43.1483 56.783 44.9043 55.6048 44.2463 56.3333C43.5648 57.0618 43.7511 51.0435 43.7511 52.3595C43.7511 53.4405 43.6653 53.0133 44.1823 53.7418C44.8403 54.6348 41.7134 54.2598 43.0764 54.2598C43.9459 54.2598 43.4702 56.9103 44.0342 56.5108C44.5982 56.1113 44.1288 57.5428 44.3873 56.7673L43.7511 56.2254C55.3795 71.8986 44.3938 54.9384 44.1823 55.1029C43.9708 55.2674 44.0801 54.2598 43.7511 54.2598C56.2643 69.3767 58.4567 71.4935 44.1823 55.1029C57.894 68.7712 44.3873 57.3783 44.3873 56.7673L44.1823 56.945C44.1823 55.3705 44.7157 57.2628 44.0342 56.5108ZM44.3873 54.5713C44.3873 54.0073 43.7522 56.8398 44.0342 56.5108C44.3397 56.1818 43.495 56.2254 43.965 56.2254C44.388 56.2254 55.4258 75.7185 43.7511 56.2254C44.0566 56.5309 44.1588 56.1955 44.1823 56.783L44.3873 54.5713Z"
|
||||
fill="#00C7FD"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_16_93">
|
||||
<rect x="0.5" y="0.238312" width="47" height="47" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg> -->
|
||||
@@ -0,0 +1,68 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
export let overrideClasses = "";
|
||||
|
||||
const classes = overrideClasses ? overrideClasses : `w-5 h-5 text-gray-400`;
|
||||
</script>
|
||||
|
||||
<!-- <svg
|
||||
class={classes}
|
||||
width="10"
|
||||
height="10"
|
||||
fill="none"
|
||||
viewBox="0 0 18 18"
|
||||
style="min-width: 18px; min-height: 18px;"
|
||||
><g
|
||||
><path
|
||||
fill="#3369FF"
|
||||
d="M15.71 8.019 3.835 1.368a1.125 1.125 0 0 0-1.61 1.36l2.04 5.71h5.298a.562.562 0 1 1 0 1.125H4.264l-2.04 5.71a1.128 1.128 0 0 0 1.058 1.506c.194 0 .384-.05.552-.146l11.877-6.65a1.125 1.125 0 0 0 0-1.964Z"
|
||||
/></g
|
||||
></svg
|
||||
> -->
|
||||
<!--
|
||||
<svg
|
||||
class={classes}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
stroke-width="1.5"
|
||||
stroke="currentColor"
|
||||
>
|
||||
<path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
d="M6 12L3.269 3.126A59.768 59.768 0 0121.485 12 59.77 59.77 0 013.27 20.876L5.999 12zm0 0h7.5"
|
||||
/>
|
||||
</svg> -->
|
||||
|
||||
<svg
|
||||
t="1708926517502"
|
||||
class={classes}
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="4586"
|
||||
id="mx_n_1708926517503"
|
||||
width="200"
|
||||
height="200"
|
||||
><path
|
||||
d="M0 1024l106.496-474.112 588.8-36.864-588.8-39.936-106.496-473.088 1024 512z"
|
||||
p-id="4587"
|
||||
fill="#0068b5"
|
||||
/></svg
|
||||
>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<!-- <svg
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="32"
|
||||
height="32"
|
||||
>
|
||||
<path d="M512 512c93.866667 0 170.666667-76.8 170.666667-170.666667 0-93.866667-76.8-170.666667-170.666667-170.666667C418.133333 170.666667 341.333333 247.466667 341.333333 341.333333 341.333333 435.2 418.133333 512 512 512zM512 597.333333c-115.2 0-341.333333 55.466667-341.333333 170.666667l0 85.333333 682.666667 0 0-85.333333C853.333333 652.8 627.2 597.333333 512 597.333333z" p-id="4050" fill="#ffffff"></path></svg> -->
|
||||
|
||||
<svg t="1708914168912" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1581" width="200" height="200"><path d="M447.13 46.545h101.818v930.91H447.13V46.545z" fill="#0068b5" p-id="1582" data-spm-anchor-id="a313x.search_index.0.i0.12a13a81x9rPe6" class="selected"></path></svg>
|
||||
94
DocSum/ui/svelte/src/lib/assets/layout/css/driver.css
Normal file
@@ -0,0 +1,94 @@
|
||||
.driverjs-theme {
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.driver-popover-arrow {
|
||||
border: 10px solid transparent;
|
||||
animation: blink 1s 3 steps(1);
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.driver-popover.driverjs-theme .driver-popover-arrow-side-left.driver-popover-arrow {
|
||||
border-left-color: #174ed1;
|
||||
}
|
||||
|
||||
.driver-popover.driverjs-theme .driver-popover-arrow-side-right.driver-popover-arrow {
|
||||
border-right-color: #174ed1;
|
||||
}
|
||||
|
||||
.driver-popover.driverjs-theme .driver-popover-arrow-side-top.driver-popover-arrow {
|
||||
border-top-color: #174ed1;
|
||||
}
|
||||
|
||||
.driver-popover.driverjs-theme .driver-popover-arrow-side-bottom.driver-popover-arrow {
|
||||
border-bottom-color: #174ed1;
|
||||
}
|
||||
|
||||
.driver-popover-footer {
|
||||
background: transparent;
|
||||
color: #fff;
|
||||
}
|
||||
.driver-popover-title {
|
||||
border-top-left-radius: 5px;
|
||||
border-top-right-radius: 5px;
|
||||
}
|
||||
|
||||
.driver-popover-title,
|
||||
.driver-popover-description {
|
||||
display: block;
|
||||
padding: 15px 15px 7px 15px;
|
||||
background: #174ed1;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.driver-popover-close-btn {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.driver-popover-footer button:hover,
|
||||
.driver-popover-footer button:focus {
|
||||
background: #174ed1;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.driver-popover-description {
|
||||
padding: 5px 15px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
}
|
||||
|
||||
.driver-popover-title[style*="block"] + .driver-popover-description {
|
||||
margin: 0;
|
||||
}
|
||||
.driver-popover-progress-text {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.driver-popover-footer button {
|
||||
background: #174ed1;
|
||||
border: 2px #174ed1 dashed;
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
text-shadow: none;
|
||||
}
|
||||
.driver-popover-close-btn:hover,
|
||||
.driver-popover-close-btn:focus {
|
||||
color: #fff;
|
||||
}
|
||||
.driver-popover-navigation-btns button + button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
31
DocSum/ui/svelte/src/lib/assets/upload/next.svelte
Normal file
@@ -0,0 +1,31 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<svg
|
||||
class="h-4 w-4 text-white rtl:rotate-180 dark:text-white-800"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 6 10"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="m1 9 4-4-4-4"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 881 B |
31
DocSum/ui/svelte/src/lib/assets/upload/previous.svelte
Normal file
@@ -0,0 +1,31 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
|
||||
<svg
|
||||
class="h-4 w-4 text-white rtl:rotate-180 dark:text-white-800"
|
||||
aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 6 10"
|
||||
>
|
||||
<path
|
||||
stroke="currentColor"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M5 1 1 5l4 4"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 881 B |
1
DocSum/ui/svelte/src/lib/assets/voice/svg/paste.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1699596229588" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="20460" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><path d="M576 128a96 96 0 0 1 96 96v128h-224a96 96 0 0 0-95.84 90.368L352 448v224H224a96 96 0 0 1-96-96V224a96 96 0 0 1 96-96h352z" fill="#CCD9FF" p-id="20461"></path><path d="M576 96a128 128 0 0 1 128 128v128h-64V224a64 64 0 0 0-59.2-63.84L576 160H224a64 64 0 0 0-64 64v352a64 64 0 0 0 64 64h128v64H224a128 128 0 0 1-128-128V224a128 128 0 0 1 128-128z" fill="#3671FD" p-id="20462"></path><path d="M800 320H448a128 128 0 0 0-128 128v352a128 128 0 0 0 128 128h352a128 128 0 0 0 128-128V448a128 128 0 0 0-128-128z m-352 64h352a64 64 0 0 1 64 64v352a64 64 0 0 1-64 64H448a64 64 0 0 1-64-64V448a64 64 0 0 1 64-64z" fill="#3671FD" p-id="20463"></path><path d="M128 736a32 32 0 0 1 32 32 96 96 0 0 0 90.368 95.84L256 864a32 32 0 0 1 0 64 160 160 0 0 1-160-160 32 32 0 0 1 32-32z" fill="#FE9C23" p-id="20464"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
DocSum/ui/svelte/src/lib/assets/voice/svg/uploadFile.svg
Normal file
|
After Width: | Height: | Size: 14 KiB |
68
DocSum/ui/svelte/src/lib/modules/chat/ChatMessage.svelte
Normal file
@@ -0,0 +1,68 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import MessageAvatar from "$lib/modules/chat/MessageAvatar.svelte";
|
||||
import type { Message } from "$lib/shared/constant/Interface";
|
||||
import MessageTimer from "./MessageTimer.svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
let dispatch = createEventDispatcher();
|
||||
|
||||
export let msg: Message;
|
||||
export let time: string = "";
|
||||
console.log("msg", msg);
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={msg.role === 0
|
||||
? "flex w-full gap-3"
|
||||
: "flex w-full items-center gap-3"}
|
||||
>
|
||||
<div
|
||||
class={msg.role === 0
|
||||
? "flex aspect-square w-[3px] items-center justify-center rounded bg-[#0597ff] max-sm:hidden"
|
||||
: "flex aspect-square h-10 w-[3px] items-center justify-center rounded bg-[#000] max-sm:hidden"}
|
||||
>
|
||||
<MessageAvatar role={msg.role} />
|
||||
</div>
|
||||
<div class="group relative items-center">
|
||||
<div>
|
||||
<p
|
||||
class=" max-w-[60vw] items-center whitespace-pre-line break-keep text-[0.8rem] leading-5 sm:max-w-[50rem]"
|
||||
>
|
||||
{@html msg.content}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if time}
|
||||
<div>
|
||||
<MessageTimer
|
||||
{time}
|
||||
on:handleTop={() => {
|
||||
dispatch("scrollTop");
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.wrap-style {
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
30
DocSum/ui/svelte/src/lib/modules/chat/MessageAvatar.svelte
Normal file
@@ -0,0 +1,30 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import AssistantIcon from "$lib/assets/chat/svelte/Assistant.svelte";
|
||||
import PersonOutlined from "$lib/assets/chat/svelte/PersonOutlined.svelte";
|
||||
import { MessageRole } from "$lib/shared/constant/Interface";
|
||||
export let role: MessageRole;
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
{#if role === MessageRole.User}
|
||||
<PersonOutlined />
|
||||
{:else}
|
||||
<AssistantIcon />
|
||||
{/if}
|
||||
67
DocSum/ui/svelte/src/lib/modules/chat/MessageTimer.svelte
Normal file
@@ -0,0 +1,67 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
export let time: string;
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
let dispatch = createEventDispatcher();
|
||||
</script>
|
||||
|
||||
<div class="ml-2 flex flex-col">
|
||||
<div class="my-4 flex items-center justify-end gap-2 space-x-2">
|
||||
<div class="ml-2 w-min cursor-pointer" data-state="closed">
|
||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xml:space="preserve"
|
||||
viewBox="0 0 21.6 21.6"
|
||||
width="24"
|
||||
height="24"
|
||||
class="w-5 fill-[#0597ff] hover:fill-[#0597ff]"
|
||||
on:click={() => {
|
||||
dispatch("handleTop");
|
||||
}}
|
||||
><path
|
||||
d="M2.2 3.6V.8h17.2v2.8zm7.2 17.2V10.4L5.8 14l-1.9-1.9 6.9-6.9 6.9 6.9-1.9 1.9-3.6-3.6v10.4z"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
class="inline-block w-0.5 self-stretch bg-gray-300 opacity-100 dark:opacity-50"
|
||||
/>
|
||||
<div class="w-min cursor-pointer" data-state="closed">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xml:space="preserve"
|
||||
viewBox="0 0 21.6 21.6"
|
||||
width="24"
|
||||
height="24"
|
||||
class="w-5 fill-[#0597ff] hover:fill-[#0597ff]"
|
||||
><path d="M12.3 17.1V7.6H7.6v2.8h1.9v6.7H6.4v2.7h8.8v-2.7z" /><circle
|
||||
cx="10.8"
|
||||
cy="3.6"
|
||||
r="1.9"
|
||||
/></svg
|
||||
>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1 text-base text-gray-800">
|
||||
<strong>End to End Time: </strong>
|
||||
<p>{time}s</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-2 flex flex-col" />
|
||||
</div>
|
||||
48
DocSum/ui/svelte/src/lib/modules/frame/Layout.svelte
Normal file
@@ -0,0 +1,48 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount } from "svelte";
|
||||
import { page } from "$app/stores";
|
||||
import { browser } from "$app/environment";
|
||||
import { open } from "$lib/shared/stores/common/Store";
|
||||
import Scrollbar from "$lib/shared/components/scrollbar/Scrollbar.svelte";
|
||||
|
||||
let root: HTMLElement
|
||||
onMount(() => {
|
||||
document.getElementsByTagName("body").item(0)!.removeAttribute("tabindex");
|
||||
// root.style.height = document.documentElement.clientHeight + 'px'
|
||||
});
|
||||
|
||||
if (browser) {
|
||||
page.subscribe(() => {
|
||||
// close side navigation when route changes
|
||||
if (window.innerWidth > 768) {
|
||||
$open = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div bind:this={root} class='h-full overflow-hidden relative'>
|
||||
<div class="h-full flex items-start">
|
||||
<div class='relative flex flex-col h-full pl-0 w-full bg-white'>
|
||||
<Scrollbar className="h-0 grow " classLayout="h-full" alwaysVisible={false}>
|
||||
<slot />
|
||||
</Scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
33
DocSum/ui/svelte/src/lib/network/chat/Network.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { env } from "$env/dynamic/public";
|
||||
import { SSE } from "sse.js";
|
||||
|
||||
const CHAT_BASE_URL = env.CHAT_BASE_URL;
|
||||
|
||||
export async function fetchTextStream(query: string, knowledge_base_id: string) {
|
||||
let payload = {};
|
||||
let url = "";
|
||||
|
||||
payload = {
|
||||
query: query,
|
||||
};
|
||||
url = `${CHAT_BASE_URL}`;
|
||||
|
||||
return new SSE(url, {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
payload: JSON.stringify(payload),
|
||||
});
|
||||
}
|
||||
58
DocSum/ui/svelte/src/lib/network/upload/Network.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
// Copyright (c) 2024 Intel Corporation
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { env } from "$env/dynamic/public";
|
||||
|
||||
const UPLOAD_FILE_BASE_URL = env.UPLOAD_FILE_BASE_URL;
|
||||
const PASTE_LINK_BASE_URL = env.PASTE_LINK_BASE_URL;
|
||||
|
||||
export async function fetchKnowledgeBaseId(file: Blob, fileName: string) {
|
||||
const url = `${UPLOAD_FILE_BASE_URL}`;
|
||||
const formData = new FormData();
|
||||
formData.append("file", file, fileName);
|
||||
const init: RequestInit = {
|
||||
method: "POST",
|
||||
body: formData,
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(url, init);
|
||||
if (!response.ok) throw response.status;
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error("network error: ", error);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchKnowledgeBaseIdByPaste(pasteUrlList: any, urlType: string | undefined) {
|
||||
const url = `${PASTE_LINK_BASE_URL}`;
|
||||
const data = {
|
||||
link_list: pasteUrlList,
|
||||
};
|
||||
const init: RequestInit = {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(data),
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch(url, init);
|
||||
if (!response.ok) throw response.status;
|
||||
return await response.json();
|
||||
} catch (error) {
|
||||
console.error("network error: ", error);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
@@ -24,3 +24,31 @@ export function scrollToBottom(scrollToDiv: HTMLElement) {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function scrollToTop(scrollToDiv: HTMLElement) {
|
||||
if (scrollToDiv) {
|
||||
setTimeout(
|
||||
() =>
|
||||
scrollToDiv.scroll({
|
||||
behavior: "auto",
|
||||
top: 0,
|
||||
}),
|
||||
100,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function getCurrentTimeStamp() {
|
||||
return Math.floor(new Date().getTime());
|
||||
}
|
||||
|
||||
export function fromTimeStampToTime(timeStamp: number) {
|
||||
return new Date(timeStamp * 1000).toTimeString().slice(0, 8);
|
||||
}
|
||||
|
||||
export function formatTime(seconds) {
|
||||
const hours = String(Math.floor(seconds / 3600)).padStart(2, "0");
|
||||
const minutes = String(Math.floor((seconds % 3600) / 60)).padStart(2, "0");
|
||||
const remainingSeconds = String(seconds % 60).padStart(2, "0");
|
||||
return `${hours}:${minutes}:${remainingSeconds}`;
|
||||
}
|
||||
|
||||
156
DocSum/ui/svelte/src/lib/shared/components/chat/gallery.svelte
Normal file
@@ -0,0 +1,156 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import Scrollbar from "$lib/shared/components/scrollbar/Scrollbar.svelte";
|
||||
import ChatMessage from "$lib/modules/chat/ChatMessage.svelte";
|
||||
import "driver.js/dist/driver.css";
|
||||
import "$lib/assets/layout/css/driver.css";
|
||||
import Previous from "$lib/assets/upload/previous.svelte";
|
||||
import Next from "$lib/assets/upload/next.svelte";
|
||||
import { scrollToBottom } from "$lib/shared/Utils";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
let scrollToDiv: HTMLDivElement;
|
||||
|
||||
export let items;
|
||||
export let label: string;
|
||||
export let scrollName: string;
|
||||
|
||||
onMount(async () => {
|
||||
scrollToDiv = document
|
||||
.querySelector(scrollName)
|
||||
?.querySelector(".svlr-viewport")!;
|
||||
console.log(
|
||||
"scrollToDiv",
|
||||
scrollName,
|
||||
document,
|
||||
document.querySelector("chat-scrollbar1")
|
||||
);
|
||||
});
|
||||
// gallery
|
||||
let currentIndex = 0;
|
||||
|
||||
function nextItem() {
|
||||
currentIndex = (currentIndex + 1) % items.length;
|
||||
console.log("nextItem", currentIndex);
|
||||
}
|
||||
|
||||
function prevItem() {
|
||||
currentIndex = (currentIndex - 1 + items.length) % items.length;
|
||||
console.log("prevItem", currentIndex);
|
||||
}
|
||||
|
||||
$: currentItem = items[currentIndex];
|
||||
|
||||
$: {
|
||||
if (items) {
|
||||
scrollToBottom(scrollToDiv);
|
||||
}
|
||||
}
|
||||
// gallery
|
||||
</script>
|
||||
|
||||
<div
|
||||
id="custom-controls-gallery"
|
||||
class="relative mb-8 h-0 w-full w-full grow px-2 {scrollName}"
|
||||
data-carousel="slide"
|
||||
>
|
||||
<!-- Carousel wrapper -->
|
||||
<!-- Display current item -->
|
||||
{#if currentItem}
|
||||
<Scrollbar
|
||||
classLayout="flex flex-col gap-5"
|
||||
className=" h-0 w-full grow px-2 mt-3 ml-10"
|
||||
>
|
||||
{#each currentItem.content as message, i}
|
||||
<ChatMessage msg={message} />
|
||||
{/each}
|
||||
</Scrollbar>
|
||||
<!-- Loading text -->
|
||||
{/if}
|
||||
|
||||
<div class="radius absolute left-0 p-2">
|
||||
<!-- Display end to end time -->
|
||||
<label for="" class="mr-2 text-xs font-bold text-blue-700">{label} </label>
|
||||
</div>
|
||||
{#if currentItem.time !== "0s"}
|
||||
<div class="radius absolute right-0 p-2">
|
||||
<!-- Display end to end time -->
|
||||
<label for="" class="mr-2 text-xs font-bold text-blue-700"
|
||||
>End to End Time:
|
||||
</label>
|
||||
<label for="" class="text-xs">{currentItem.time}</label>
|
||||
</div>
|
||||
{/if}
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="justify-left ml-2 flex items-center">
|
||||
<!-- Previous button -->
|
||||
<button
|
||||
type="button"
|
||||
class="group absolute start-0 top-0 z-30 flex h-full
|
||||
cursor-pointer items-center justify-center
|
||||
focus:outline-none"
|
||||
on:click={prevItem}
|
||||
>
|
||||
<span
|
||||
class="group-focus:ring-gray dark:group-hover:bg-[#000]-800/60 dark:group-focus:ring-[#000]-800/70 inline-flex h-7
|
||||
w-7 items-center justify-center
|
||||
rounded-full bg-[#000]/10
|
||||
group-hover:bg-[#000]/50 group-focus:bg-[#000]/50
|
||||
group-focus:outline-none
|
||||
group-focus:ring-4 dark:bg-gray-800/30"
|
||||
>
|
||||
<Previous />
|
||||
<span class="sr-only">Previous</span>
|
||||
</span>
|
||||
</button>
|
||||
<!-- Next button -->
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="group absolute end-0 top-0 z-30 flex h-full cursor-pointer items-center justify-center focus:outline-none"
|
||||
on:click={nextItem}
|
||||
>
|
||||
<span
|
||||
class="group-focus:ring-gray dark:group-hover:bg-[#000]-800/60 dark:group-focus:ring-[#000]-800/70 inline-flex h-7
|
||||
w-7 items-center justify-center
|
||||
rounded-full bg-[#000]/10
|
||||
group-hover:bg-[#000]/50 group-focus:bg-[#000]/50
|
||||
group-focus:outline-none
|
||||
group-focus:ring-4 dark:bg-gray-800/30"
|
||||
>
|
||||
<Next />
|
||||
<span class="sr-only">Next</span>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.row::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.row {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,48 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<div
|
||||
class="mb-6 flex items-center justify-center self-center bg-black text-sm text-gray-500"
|
||||
/>
|
||||
<div class="flex items-center justify-center gap-3">
|
||||
<div class="relative inline-flex">
|
||||
<div class="h-2 w-2 rounded-full bg-blue-600" />
|
||||
<div
|
||||
class="absolute left-0 top-0 h-2 w-2 animate-[ping_1s_infinite_100ms] rounded-full bg-blue-600"
|
||||
/>
|
||||
<div
|
||||
class="duration-800 absolute left-0 top-0 h-2 w-2 animate-pulse rounded-full bg-blue-600"
|
||||
/>
|
||||
</div>
|
||||
<div class="relative inline-flex">
|
||||
<div class="h-2 w-2 rounded-full bg-blue-600" />
|
||||
<div
|
||||
class="absolute left-0 top-0 h-2 w-2 animate-[ping_1s_infinite_300ms] rounded-full bg-blue-600"
|
||||
/>
|
||||
<div
|
||||
class="absolute left-0 top-0 h-2 w-2 animate-pulse rounded-full bg-blue-600"
|
||||
/>
|
||||
</div>
|
||||
<div class="relative inline-flex">
|
||||
<div class="h-2 w-2 rounded-full bg-blue-600" />
|
||||
<div
|
||||
class="absolute left-0 top-0 h-2 w-2 animate-[ping_1s_infinite_500ms] rounded-full bg-blue-600"
|
||||
/>
|
||||
<div
|
||||
class="absolute left-0 top-0 h-2 w-2 animate-pulse rounded-full bg-blue-600"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,48 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { Svroller } from "svrollbar";
|
||||
export let className: string = "";
|
||||
export let classLayout: string = "";
|
||||
export let alwaysVisible = true;
|
||||
</script>
|
||||
|
||||
<div class={className}>
|
||||
<Svroller height="100%" width="100%" {alwaysVisible}>
|
||||
<div class={classLayout}>
|
||||
<slot></slot>
|
||||
</div>
|
||||
</Svroller>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
:global(.svlr-contents) {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.row::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.row {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,52 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { Button, Helper, Input, Label, Modal } from "flowbite-svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
let formModal = false;
|
||||
let urlValue = "";
|
||||
|
||||
function handelPasteURL() {
|
||||
const pasteUrlList = urlValue.split(";").map((url) => url.trim());
|
||||
dispatch("paste", { pasteUrlList });
|
||||
formModal = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<Label class="space-y-1">
|
||||
<div class="grid grid-cols-3">
|
||||
<Input
|
||||
class="col-span-2 rounded-none rounded-l-lg focus:border-blue-700 focus:ring-blue-700"
|
||||
type="text"
|
||||
name="text"
|
||||
placeholder="URL"
|
||||
bind:value={urlValue}
|
||||
data-testid="paste-link"
|
||||
/>
|
||||
<Button
|
||||
type="submit"
|
||||
class="w-full rounded-none rounded-r-lg bg-blue-700"
|
||||
data-testid="paste-click"
|
||||
|
||||
on:click={() => handelPasteURL()}>Confirm</Button
|
||||
>
|
||||
</div>
|
||||
|
||||
<Helper>Use semicolons (;) to separate multiple URLs.</Helper>
|
||||
</Label>
|
||||
@@ -0,0 +1,48 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { Fileupload, Label } from "flowbite-svelte";
|
||||
import { createEventDispatcher } from "svelte";
|
||||
|
||||
const dispatch = createEventDispatcher();
|
||||
let value;
|
||||
|
||||
function handleInput(event: Event) {
|
||||
const file = (event.target as HTMLInputElement).files![0];
|
||||
|
||||
if (!file) return;
|
||||
|
||||
const reader = new FileReader();
|
||||
reader.onloadend = () => {
|
||||
if (!reader.result) return;
|
||||
const src = reader.result.toString();
|
||||
dispatch("upload", { src: src, fileName: file.name });
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<Label class="space-y-2 mb-2">
|
||||
<Fileupload
|
||||
bind:value
|
||||
on:change={handleInput}
|
||||
class="focus:border-blue-700 focus:ring-0"
|
||||
data-testid="file-upload"
|
||||
/>
|
||||
</Label>
|
||||
@@ -0,0 +1,167 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import { Drawer, Button, CloseButton, Tabs, TabItem } from "flowbite-svelte";
|
||||
import { InfoCircleSolid } from "flowbite-svelte-icons";
|
||||
import { sineIn } from "svelte/easing";
|
||||
import UploadFile from "./upload-knowledge.svelte";
|
||||
import PasteURL from "./PasteKnowledge.svelte";
|
||||
import {
|
||||
knowledge1,
|
||||
knowledgeName,
|
||||
} from "$lib/shared/stores/common/Store";
|
||||
import DeleteIcon from "$lib/assets/avatar/svelte/Delete.svelte";
|
||||
import { getNotificationsContext } from "svelte-notifications";
|
||||
import {
|
||||
fetchKnowledgeBaseId,
|
||||
fetchKnowledgeBaseIdByPaste,
|
||||
} from "$lib/network/upload/Network";
|
||||
|
||||
const { addNotification } = getNotificationsContext();
|
||||
console.log("allKnowledges", $knowledgeName);
|
||||
|
||||
let hidden6 = true;
|
||||
let selectKnowledge = -1;
|
||||
let transitionParamsRight = {
|
||||
x: 320,
|
||||
duration: 200,
|
||||
easing: sineIn,
|
||||
};
|
||||
|
||||
async function handleKnowledgePaste(
|
||||
e: CustomEvent<{ pasteUrlList: string[] }>
|
||||
) {
|
||||
let knowledge_id = "";
|
||||
// let knowledge_id2 = "";
|
||||
try {
|
||||
const pasteUrlList = e.detail.pasteUrlList;
|
||||
const res = await fetchKnowledgeBaseIdByPaste(pasteUrlList, "url1");
|
||||
// sihan
|
||||
knowledge_id = res.knowledge_base_id ? res.knowledge_base_id : "default";
|
||||
} catch {
|
||||
knowledge_id = "default";
|
||||
}
|
||||
knowledge1.set({ id: knowledge_id });
|
||||
knowledgeName.set('knowledge_base');
|
||||
|
||||
addNotification({
|
||||
text: "Uploaded successfully",
|
||||
position: "top-left",
|
||||
type: "success",
|
||||
removeAfter: 3000,
|
||||
});
|
||||
}
|
||||
|
||||
async function handleKnowledgeUpload(e: CustomEvent<any>) {
|
||||
let knowledge_id = "";
|
||||
// let knowledge_id2 = "";
|
||||
try {
|
||||
const blob = await fetch(e.detail.src).then((r) => r.blob());
|
||||
const fileName = e.detail.fileName;
|
||||
// letong
|
||||
const res = await fetchKnowledgeBaseId(blob, fileName);
|
||||
// sihan
|
||||
knowledge_id = res.knowledge_base_id ? res.knowledge_base_id : "default";
|
||||
// knowledge_id2 = res2.knowledge_base_id ? res2.knowledge_base_id : "default";
|
||||
console.log("knowledge_id", knowledge_id);
|
||||
} catch {
|
||||
knowledge_id = "default";
|
||||
// knowledge_id2 = "default";
|
||||
}
|
||||
knowledge1.set({ id: knowledge_id });
|
||||
knowledgeName.set(e.detail.fileName);
|
||||
addNotification({
|
||||
text: "Uploaded successfully",
|
||||
position: "top-left",
|
||||
type: "success",
|
||||
removeAfter: 3000,
|
||||
});
|
||||
}
|
||||
|
||||
function handleKnowledgeDelete() {
|
||||
knowledge1.set({ id: "default" });
|
||||
knowledgeName.set("");
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="text-center">
|
||||
<Button
|
||||
on:click={() => (hidden6 = false)}
|
||||
class="bg-transparent focus-within:ring-gray-300 hover:bg-transparent focus:ring-0"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class="h-7 w-7 text-blue-700"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
><path
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="2"
|
||||
d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"
|
||||
/></svg
|
||||
>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Drawer
|
||||
backdrop={false}
|
||||
placement="right"
|
||||
transitionType="fly"
|
||||
transitionParams={transitionParamsRight}
|
||||
bind:hidden={hidden6}
|
||||
class=" shadow border-2 border-r-0 border-b-0"
|
||||
id="sidebar6"
|
||||
>
|
||||
<div class="flex items-center">
|
||||
<h5
|
||||
id="drawer-label"
|
||||
class="mb-4 inline-flex items-center text-base font-semibold text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
<InfoCircleSolid class="me-2.5 h-4 w-4" />Data Source
|
||||
</h5>
|
||||
<CloseButton
|
||||
on:click={() => (hidden6 = true)}
|
||||
class="mb-4 dark:text-white"
|
||||
/>
|
||||
</div>
|
||||
<p class="mb-6 text-sm text-gray-500 dark:text-gray-400">
|
||||
Please upload your local file or paste a remote file link, and Chat will
|
||||
respond based on the content of the uploaded file.
|
||||
</p>
|
||||
<Tabs
|
||||
style="full"
|
||||
defaultClass="flex rounded-lg divide-x rtl:divide-x-reverse divide-gray-200 shadow dark:divide-gray-700 focus:ring-0"
|
||||
>
|
||||
<TabItem class="w-full" open>
|
||||
<span slot="title">Upload File</span>
|
||||
<UploadFile on:upload={handleKnowledgeUpload} />
|
||||
</TabItem>
|
||||
<TabItem class="w-full">
|
||||
<span slot="title">Paste Link</span>
|
||||
<PasteURL on:paste={handleKnowledgePaste} />
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
{#if ($knowledgeName) && ($knowledgeName !== "")}
|
||||
<div class="relative">
|
||||
<p class="border-b p-6 pb-2">{$knowledgeName}</p>
|
||||
<DeleteIcon on:DeleteAvatar={() => handleKnowledgeDelete()} />
|
||||
</div>
|
||||
{/if}
|
||||
</Drawer>
|
||||
47
DocSum/ui/svelte/src/lib/shared/constant/Interface.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
// 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.
|
||||
|
||||
export enum MessageRole {
|
||||
Assistant,
|
||||
User,
|
||||
}
|
||||
|
||||
export enum MessageType {
|
||||
Text,
|
||||
SingleAudio,
|
||||
AudioList,
|
||||
SingleImage,
|
||||
ImageList,
|
||||
singleVideo,
|
||||
}
|
||||
|
||||
type Map<T> = T extends MessageType.Text | MessageType.SingleAudio
|
||||
? string
|
||||
: T extends MessageType.AudioList
|
||||
? string[]
|
||||
: T extends MessageType.SingleImage
|
||||
? { imgSrc: string; imgId: string }
|
||||
: { imgSrc: string; imgId: string }[];
|
||||
|
||||
export interface Message {
|
||||
role: MessageRole;
|
||||
type: MessageType;
|
||||
content: Map<Message["type"]>;
|
||||
time: number;
|
||||
}
|
||||
|
||||
export enum LOCAL_STORAGE_KEY {
|
||||
STORAGE_CHAT_KEY = "chatMessages",
|
||||
STORAGE_TIME_KEY = "initTime",
|
||||
}
|
||||
39
DocSum/ui/svelte/src/lib/shared/stores/common/Store.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
// 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 { writable } from "svelte/store";
|
||||
|
||||
export let open = writable(true);
|
||||
|
||||
export let knowledgeAccess = writable(true);
|
||||
|
||||
export let showTemplate = writable(false);
|
||||
|
||||
export let showSidePage = writable(false);
|
||||
|
||||
export let droppedObj = writable({});
|
||||
|
||||
export let isLoading = writable(false);
|
||||
|
||||
export let newUploadNum = writable(0);
|
||||
|
||||
export let ifStoreMsg = writable(true);
|
||||
|
||||
export const resetControl = writable(false);
|
||||
|
||||
export const knowledge1 = writable<{
|
||||
id: string;
|
||||
}>();
|
||||
|
||||
export const knowledgeName = writable("");
|
||||
@@ -15,11 +15,34 @@
|
||||
-->
|
||||
|
||||
<script>
|
||||
import "../app.pcss";
|
||||
import "tailwindcss/tailwind.css";
|
||||
import "../app.postcss";
|
||||
import Notifications from "svelte-notifications";
|
||||
import Layout from "$lib/modules/frame/Layout.svelte";
|
||||
import { onMount } from "svelte";
|
||||
|
||||
onMount(() => {
|
||||
window.deviceType = window.innerWidth > 640 ? "pc" : "mobile";
|
||||
window.onresize = () => {
|
||||
window.deviceType = window.innerWidth > 640 ? "pc" : "mobile";
|
||||
};
|
||||
window.addEventListener("load", function () {
|
||||
setTimeout(function () {
|
||||
// This hides the address bar:
|
||||
window.scrollTo(0, 1);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
<Notifications>
|
||||
<Layout>
|
||||
<div class="flex h-full flex-col">
|
||||
<div class="h-0 grow bg-white lg:rounded-tl-3xl">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</Layout>
|
||||
</Notifications>
|
||||
|
||||
@@ -15,80 +15,254 @@
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import Header from "$lib/header.svelte";
|
||||
import Doc from "$lib/doc.svelte";
|
||||
import Summary from "$lib/summary.svelte";
|
||||
import { fetchTextStream } from "$lib/shared/Network.js";
|
||||
import { loading } from "$lib/shared/Store.js";
|
||||
export let data;
|
||||
import { ifStoreMsg, knowledge1 } from "$lib/shared/stores/common/Store";
|
||||
import { onMount } from "svelte";
|
||||
import { scrollToBottom } from "$lib/shared/Utils.js";
|
||||
import {
|
||||
LOCAL_STORAGE_KEY,
|
||||
MessageRole,
|
||||
MessageType,
|
||||
type Message,
|
||||
} from "$lib/shared/constant/Interface";
|
||||
import {
|
||||
fromTimeStampToTime,
|
||||
getCurrentTimeStamp,
|
||||
scrollToBottom,
|
||||
scrollToTop,
|
||||
} from "$lib/shared/Utils";
|
||||
import { fetchTextStream } from "$lib/network/chat/Network";
|
||||
import LoadingAnimation from "$lib/shared/components/loading/Loading.svelte";
|
||||
import { browser } from "$app/environment";
|
||||
import "driver.js/dist/driver.css";
|
||||
import "$lib/assets/layout/css/driver.css";
|
||||
import UploadFile from "$lib/shared/components/upload/uploadFile.svelte";
|
||||
import PaperAirplane from "$lib/assets/chat/svelte/PaperAirplane.svelte";
|
||||
import Gallery from "$lib/shared/components/chat/gallery.svelte";
|
||||
import Scrollbar from "$lib/shared/components/scrollbar/Scrollbar.svelte";
|
||||
import ChatMessage from "$lib/modules/chat/ChatMessage.svelte";
|
||||
|
||||
let messages = '';
|
||||
let query: string = "";
|
||||
let loading: boolean = false;
|
||||
let scrollToDiv: HTMLDivElement;
|
||||
// ·········
|
||||
let chatMessages: Message[] = data.chatMsg ? data.chatMsg : [];
|
||||
console.log("chatMessages", chatMessages);
|
||||
|
||||
onMount(() => {
|
||||
// ··············
|
||||
|
||||
$: knowledge_1 = $knowledge1?.id ? $knowledge1.id : "default";
|
||||
|
||||
onMount(async () => {
|
||||
scrollToDiv = document
|
||||
.querySelector("#editor")!
|
||||
console.log('scrollToDiv', scrollToDiv);
|
||||
.querySelector(".chat-scrollbar")
|
||||
?.querySelector(".svlr-viewport")!;
|
||||
});
|
||||
|
||||
})
|
||||
function handleTop() {
|
||||
console.log("top");
|
||||
|
||||
const callTextStream = async (
|
||||
query: string,
|
||||
urlSuffix: string,
|
||||
params: string
|
||||
) => {
|
||||
messages = "";
|
||||
const eventSource = await fetchTextStream(query, urlSuffix, params);
|
||||
scrollToTop(scrollToDiv);
|
||||
}
|
||||
|
||||
function storeMessages() {
|
||||
console.log('localStorage', chatMessages);
|
||||
|
||||
localStorage.setItem(
|
||||
LOCAL_STORAGE_KEY.STORAGE_CHAT_KEY,
|
||||
JSON.stringify(chatMessages)
|
||||
);
|
||||
}
|
||||
|
||||
const callTextStream = async (query: string) => {
|
||||
const eventSource = await fetchTextStream(query, knowledge_1);
|
||||
|
||||
eventSource.addEventListener("message", (e: any) => {
|
||||
let Msg = e.data;
|
||||
if (Msg !== "[DONE]") {
|
||||
let res = JSON.parse(Msg);
|
||||
let logs = res.ops;
|
||||
let currentMsg = e.data;
|
||||
currentMsg = currentMsg.replace("@#$", " ")
|
||||
console.log("currentMsg", currentMsg);
|
||||
if (currentMsg == "[DONE]") {
|
||||
console.log("done getCurrentTimeStamp", getCurrentTimeStamp);
|
||||
let startTime = chatMessages[chatMessages.length - 1].time;
|
||||
|
||||
logs.forEach((log: { op: string; path: string; value: any }) => {
|
||||
if (log.op === "add") {
|
||||
if (
|
||||
log.value !== "</s>" && log.path.endsWith("/streamed_output/-") && log.path.length > "/streamed_output/-".length
|
||||
) {
|
||||
messages += log.value;
|
||||
scrollToBottom(scrollToDiv)
|
||||
loading = false;
|
||||
let totalTime = parseFloat(((getCurrentTimeStamp() - startTime) / 1000).toFixed(2));
|
||||
console.log("done totalTime", totalTime);
|
||||
console.log(
|
||||
"chatMessages[chatMessages.length - 1]",
|
||||
chatMessages[chatMessages.length - 1]
|
||||
);
|
||||
|
||||
if (chatMessages.length - 1 !== -1) {
|
||||
chatMessages[chatMessages.length - 1].time = totalTime;
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log("done chatMessages", chatMessages);
|
||||
|
||||
storeMessages();
|
||||
} else {
|
||||
loading.set(false);
|
||||
scrollToBottom(scrollToDiv)
|
||||
if (chatMessages[chatMessages.length - 1].role == MessageRole.User) {
|
||||
console.log("?", getCurrentTimeStamp());
|
||||
|
||||
chatMessages = [
|
||||
...chatMessages,
|
||||
{
|
||||
role: MessageRole.Assistant,
|
||||
type: MessageType.Text,
|
||||
content: currentMsg,
|
||||
time: getCurrentTimeStamp(),
|
||||
},
|
||||
];
|
||||
console.log("? chatMessages", chatMessages);
|
||||
} else {
|
||||
let content = chatMessages[chatMessages.length - 1].content as string;
|
||||
chatMessages[chatMessages.length - 1].content =
|
||||
content + currentMsg;
|
||||
}
|
||||
scrollToBottom(scrollToDiv);
|
||||
}
|
||||
});
|
||||
eventSource.stream();
|
||||
};
|
||||
|
||||
async function handleGenerateSummary(e) {
|
||||
if (e.detail.mode === "file") {
|
||||
await callTextStream(e.detail.value, "/file_summarize", "doc_id");
|
||||
} else if (e.detail.mode === "text") {
|
||||
await callTextStream(e.detail.value, "/text_summarize", "text");
|
||||
}
|
||||
const handleTextSubmit = async () => {
|
||||
console.log("handleTextSubmit");
|
||||
|
||||
loading = true;
|
||||
const newMessage = {
|
||||
role: MessageRole.User,
|
||||
type: MessageType.Text,
|
||||
content: query,
|
||||
time: 0,
|
||||
};
|
||||
chatMessages = [...chatMessages, newMessage];
|
||||
scrollToBottom(scrollToDiv);
|
||||
storeMessages();
|
||||
query = "";
|
||||
|
||||
await callTextStream(newMessage.content);
|
||||
|
||||
scrollToBottom(scrollToDiv);
|
||||
storeMessages();
|
||||
};
|
||||
|
||||
function handelClearHistory() {
|
||||
localStorage.removeItem(LOCAL_STORAGE_KEY.STORAGE_CHAT_KEY);
|
||||
chatMessages = [];
|
||||
}
|
||||
|
||||
function handleClearMsg(e) {
|
||||
if (e.detail.status) {
|
||||
messages = "";
|
||||
function isEmptyObject(obj: any): boolean {
|
||||
for (let key in obj) {
|
||||
if (obj.hasOwnProperty(key)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="h-full">
|
||||
<Header />
|
||||
<p class="m-7 sm:mb-0 text-gray-500 font-semibold xl:m-8">Please upload file or paste content for summarization.</p>
|
||||
<div class="mt-2 m-6 grid grid-cols-3 gap-8 h-full">
|
||||
<div class="col-span-2 h-full">
|
||||
<Doc on:generateSummary={handleGenerateSummary} on:clearMsg={handleClearMsg}/>
|
||||
<!-- <DropZone on:drop={handleImageSubmit}> -->
|
||||
<div
|
||||
class="h-full items-center gap-5 bg-white sm:flex sm:pb-2 lg:rounded-tl-3xl"
|
||||
>
|
||||
<div class="mx-auto flex h-full w-full flex-col sm:mt-0 sm:w-[72%]">
|
||||
<div class="flex justify-between p-2">
|
||||
<p class="text-[1.7rem] font-bold tracking-tight">ChatQnA</p>
|
||||
<UploadFile />
|
||||
</div>
|
||||
<div class="col-span-1">
|
||||
<Summary chatMessage={messages} />
|
||||
<div
|
||||
class="fixed relative flex w-full flex-col items-center justify-between bg-white p-2 pb-0"
|
||||
>
|
||||
<div class="relative my-4 flex w-full flex-row justify-center">
|
||||
<div class="focus:border-none relative w-full">
|
||||
<input
|
||||
class="text-md block w-full border-0 border-b-2 border-gray-300 px-1 py-4
|
||||
text-gray-900 focus:border-gray-300 focus:ring-0 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:placeholder-gray-400 dark:focus:border-blue-500 dark:focus:ring-blue-500"
|
||||
type="text"
|
||||
data-testid="chat-input"
|
||||
placeholder="Enter prompt here"
|
||||
disabled={loading}
|
||||
maxlength="1200"
|
||||
bind:value={query}
|
||||
on:keydown={(event) => {
|
||||
if (event.key === "Enter" && !event.shiftKey && query) {
|
||||
event.preventDefault();
|
||||
handleTextSubmit();
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<button
|
||||
on:click={() => {
|
||||
if (query) {
|
||||
handleTextSubmit();
|
||||
}
|
||||
}}
|
||||
type="submit"
|
||||
id="send"
|
||||
class="absolute bottom-2.5 end-2.5 px-4 py-2 text-sm font-medium text-white dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
|
||||
><PaperAirplane /></button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- clear -->
|
||||
{#if Array.isArray(chatMessages) && chatMessages.length > 0 && !loading}
|
||||
<div class="flex w-full justify-between pr-5">
|
||||
<div class="flex items-center">
|
||||
<button
|
||||
class="bg-primary text-primary-foreground hover:bg-primary/90 group flex items-center justify-center space-x-2 p-2"
|
||||
type="button"
|
||||
data-testid='clear-chat'
|
||||
on:click={() => handelClearHistory()}
|
||||
><svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20"
|
||||
width="24"
|
||||
height="24"
|
||||
class="fill-[#0597ff] group-hover:fill-[#0597ff]"
|
||||
><path
|
||||
d="M12.6 12 10 9.4 7.4 12 6 10.6 8.6 8 6 5.4 7.4 4 10 6.6 12.6 4 14 5.4 11.4 8l2.6 2.6zm7.4 8V2q0-.824-.587-1.412A1.93 1.93 0 0 0 18 0H2Q1.176 0 .588.588A1.93 1.93 0 0 0 0 2v12q0 .825.588 1.412Q1.175 16 2 16h14zm-3.15-6H2V2h16v13.125z"
|
||||
/></svg
|
||||
><span class="font-medium text-[#0597ff]">CLEAR</span></button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
<!-- clear -->
|
||||
|
||||
<div class="mx-auto flex h-full w-full flex-col">
|
||||
<Scrollbar
|
||||
classLayout="flex flex-col gap-1 mr-4"
|
||||
className="chat-scrollbar h-0 w-full grow px-2 pt-2 mt-3 mr-5"
|
||||
>
|
||||
{#each chatMessages as message, i}
|
||||
<ChatMessage
|
||||
on:scrollTop={() => handleTop()}
|
||||
msg={message}
|
||||
time={i === 0 || (message.time > 0 && message.time < 100)
|
||||
? message.time
|
||||
: ""}
|
||||
/>
|
||||
{/each}
|
||||
</Scrollbar>
|
||||
<!-- Loading text -->
|
||||
{#if loading}
|
||||
<LoadingAnimation />
|
||||
{/if}
|
||||
</div>
|
||||
<!-- gallery -->
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.row::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.row {
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.row {
|
||||
-ms-overflow-style: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
26
DocSum/ui/svelte/src/routes/+page.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
// 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 { browser } from "$app/environment";
|
||||
import { LOCAL_STORAGE_KEY } from "$lib/shared/constant/Interface";
|
||||
|
||||
export const load = async () => {
|
||||
if (browser) {
|
||||
const chat = localStorage.getItem(LOCAL_STORAGE_KEY.STORAGE_CHAT_KEY);
|
||||
|
||||
return {
|
||||
chatMsg: JSON.parse(chat || "[]"),
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -13,18 +13,21 @@
|
||||
// limitations under the License.
|
||||
|
||||
import adapter from "@sveltejs/adapter-auto";
|
||||
import { vitePreprocess } from "@sveltejs/vite-plugin-svelte";
|
||||
import preprocess from "svelte-preprocess";
|
||||
import postcssPresetEnv from "postcss-preset-env";
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// Consult https://github.com/sveltejs/svelte-preprocess
|
||||
// for more information about preprocessors
|
||||
preprocess: [vitePreprocess({})],
|
||||
preprocess: preprocess({
|
||||
sourceMap: true,
|
||||
postcss: {
|
||||
plugins: [postcssPresetEnv({ features: { "nesting-rules": true } })],
|
||||
},
|
||||
}),
|
||||
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
|
||||
adapter: adapter(),
|
||||
env: {
|
||||
publicPrefix: "",
|
||||
|
||||
@@ -24,16 +24,16 @@ const config = {
|
||||
colors: {
|
||||
// flowbite-svelte
|
||||
primary: {
|
||||
50: "#f2f8ff",
|
||||
100: "#eef5ff",
|
||||
200: "#deecff",
|
||||
300: "#cce2ff",
|
||||
400: "#add0ff",
|
||||
500: "#5da2fe",
|
||||
600: "#2f81ef",
|
||||
700: "#2780eb",
|
||||
800: "#226fcc",
|
||||
900: "#1b5aa5",
|
||||
50: "#FFF5F2",
|
||||
100: "#FFF1EE",
|
||||
200: "#FFE4DE",
|
||||
300: "#FFD5CC",
|
||||
400: "#FFBCAD",
|
||||
500: "#FE795D",
|
||||
600: "#EF562F",
|
||||
700: "#EB4F27",
|
||||
800: "#CC4522",
|
||||
900: "#A5371B",
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||