Compare commits
226 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d5972112c | ||
|
|
dab0177432 | ||
|
|
e7b000eca5 | ||
|
|
723fddec79 | ||
|
|
f629702004 | ||
|
|
4f3be23efa | ||
|
|
9657f7bc83 | ||
|
|
ac324a9ec2 | ||
|
|
dfaf47978d | ||
|
|
acbaaf8ff0 | ||
|
|
06cb308611 | ||
|
|
e6b4fff05c | ||
|
|
a54ffd2c1e | ||
|
|
f3ffcd50b3 | ||
|
|
947cbe39b8 | ||
|
|
fbb81b67db | ||
|
|
5d39506c5c | ||
|
|
566cf93c34 | ||
|
|
771975510a | ||
|
|
6674832162 | ||
|
|
67df2804de | ||
|
|
46af6f3bc4 | ||
|
|
343d614591 | ||
|
|
87617e761c | ||
|
|
db2d2bd1a1 | ||
|
|
4fa37e7842 | ||
|
|
c73e4e0f26 | ||
|
|
ba78b4c994 | ||
|
|
01c1b7504f | ||
|
|
c016d8264a | ||
|
|
4fd3517f23 | ||
|
|
503a1a9844 | ||
|
|
08f57fa54a | ||
|
|
5a9c109e35 | ||
|
|
c327972776 | ||
|
|
f45e4c6956 | ||
|
|
5dcadf3d3f | ||
|
|
3363a37197 | ||
|
|
b2771ad3f2 | ||
|
|
e81e0e557c | ||
|
|
71363a6b9d | ||
|
|
a39f23a16e | ||
|
|
c9f9acab61 | ||
|
|
040d2b7fd9 | ||
|
|
6296e9f2fb | ||
|
|
c86cf8536d | ||
|
|
039014fbbf | ||
|
|
1c07a38457 | ||
|
|
e93146b33e | ||
|
|
a6385bc6fd | ||
|
|
c26d0f62b8 | ||
|
|
e71aba0080 | ||
|
|
cfcac3f0ec | ||
|
|
d68be058f5 | ||
|
|
45cf553d36 | ||
|
|
1c23d87aa2 | ||
|
|
64bfea9054 | ||
|
|
0a6bad0ab9 | ||
|
|
4f7fc39d66 | ||
|
|
80e3e2a2d3 | ||
|
|
8c384e0314 | ||
|
|
3c9e2aaffd | ||
|
|
acdd712929 | ||
|
|
c297155bea | ||
|
|
923cf69e63 | ||
|
|
7a67298f19 | ||
|
|
a5ed2233b5 | ||
|
|
e12baca3b8 | ||
|
|
939502dba1 | ||
|
|
a072441c06 | ||
|
|
ed483719a8 | ||
|
|
14621f8492 | ||
|
|
2390920b1d | ||
|
|
02a15366bc | ||
|
|
f08d4115db | ||
|
|
5ac77f78da | ||
|
|
ebc165a6aa | ||
|
|
ad8ca8886e | ||
|
|
88eeb0d7e6 | ||
|
|
e22d41362d | ||
|
|
17b9676a3d | ||
|
|
7dd9952f5e | ||
|
|
06c4484b88 | ||
|
|
3913c7bb36 | ||
|
|
abc02e1332 | ||
|
|
cf021ee009 | ||
|
|
70a50d8b78 | ||
|
|
ab9879508f | ||
|
|
08eb2699b7 | ||
|
|
4259240407 | ||
|
|
8bdb598417 | ||
|
|
ac89855ff8 | ||
|
|
c71bc68c9c | ||
|
|
09a3196324 | ||
|
|
015a2b178b | ||
|
|
33f83293d6 | ||
|
|
076bca3bbf | ||
|
|
83712b9f1b | ||
|
|
704ec9234d | ||
|
|
c461b6081f | ||
|
|
d645305816 | ||
|
|
9277fe6201 | ||
|
|
21fab71f6d | ||
|
|
a2437e83e7 | ||
|
|
1b3398902b | ||
|
|
07921a98d0 | ||
|
|
42104fe117 | ||
|
|
1ac696bfa9 | ||
|
|
8032ce60f6 | ||
|
|
b61c2abd61 | ||
|
|
965c13c556 | ||
|
|
8f9bcd4b3c | ||
|
|
6b5489a36e | ||
|
|
8d0c8fb949 | ||
|
|
535dcc36e5 | ||
|
|
edf0d14c95 | ||
|
|
43bd8f2e4b | ||
|
|
d0b028d199 | ||
|
|
8b60948c7b | ||
|
|
268d58d4a9 | ||
|
|
5984848bb0 | ||
|
|
f4b4ac0d3a | ||
|
|
c745641ba1 | ||
|
|
1b48e54a3d | ||
|
|
8c4a2534c1 | ||
|
|
21b7d11098 | ||
|
|
e371b1e9d4 | ||
|
|
95c13d9558 | ||
|
|
62ae64f13c | ||
|
|
631d841119 | ||
|
|
665c46ffae | ||
|
|
6e797fae89 | ||
|
|
b46ae8bdcc | ||
|
|
f45f508847 | ||
|
|
284d855bf4 | ||
|
|
290a74fae9 | ||
|
|
8ad7f36fe2 | ||
|
|
2f9397e012 | ||
|
|
c9548d7921 | ||
|
|
83146320aa | ||
|
|
ecf3338835 | ||
|
|
b7975e79d8 | ||
|
|
bb42307af9 | ||
|
|
2e312f44ed | ||
|
|
ee0dcb3d37 | ||
|
|
f732674b1e | ||
|
|
d9946180a2 | ||
|
|
11a56e09ef | ||
|
|
615f0d2547 | ||
|
|
9551594164 | ||
|
|
97da49f61e | ||
|
|
8d4209a015 | ||
|
|
ba65415b78 | ||
|
|
3505bd25a4 | ||
|
|
49789595e5 | ||
|
|
ff05573d98 | ||
|
|
c37d9c82b0 | ||
|
|
89ddec9b2d | ||
|
|
d7a5b751d9 | ||
|
|
15fc6f9711 | ||
|
|
e878dc1311 | ||
|
|
377dd2fa9e | ||
|
|
335362ab11 | ||
|
|
f9312b3713 | ||
|
|
5f52a10ffe | ||
|
|
450efcc139 | ||
|
|
034541404e | ||
|
|
26d4ff11ff | ||
|
|
3bb2fee922 | ||
|
|
7ebe781ccb | ||
|
|
bbbaefacad | ||
|
|
77ba9139a1 | ||
|
|
1b307832d7 | ||
|
|
2e62ecc18a | ||
|
|
84a91bb990 | ||
|
|
7dd0506e08 | ||
|
|
ca6a8f8e1d | ||
|
|
295b81823c | ||
|
|
960cf38d33 | ||
|
|
afcb3a3523 | ||
|
|
3ffe19eba1 | ||
|
|
6f5a9932f7 | ||
|
|
83e6a23441 | ||
|
|
7f19e8b546 | ||
|
|
81ceb26c3f | ||
|
|
2f472315fd | ||
|
|
6a3e9dbc18 | ||
|
|
6b76a93eb7 | ||
|
|
b4d8e1a19b | ||
|
|
b994bc8731 | ||
|
|
d9b62a5a62 | ||
|
|
409c72350e | ||
|
|
e32a51451c | ||
|
|
e948a7f81b | ||
|
|
e80e567817 | ||
|
|
4fecd6a850 | ||
|
|
01eed84db1 | ||
|
|
a0b94b5401 | ||
|
|
a1a384e1fa | ||
|
|
654e2a0d72 | ||
|
|
c3b641f8a8 | ||
|
|
2b51374416 | ||
|
|
961abb3c05 | ||
|
|
2fb070dbfd | ||
|
|
c5f3095ea5 | ||
|
|
2a48601227 | ||
|
|
240587932b | ||
|
|
f2a94377aa | ||
|
|
5ade6865c9 | ||
|
|
29de55da3c | ||
|
|
99eb6a6a7e | ||
|
|
5715e9757e | ||
|
|
4d36def840 | ||
|
|
02c7baae2b | ||
|
|
60b1696530 | ||
|
|
b967f60536 | ||
|
|
e3289477b0 | ||
|
|
44c5cb71fa | ||
|
|
4d08310fdb | ||
|
|
26d6ea4724 | ||
|
|
4250048b18 | ||
|
|
422b4bc56b | ||
|
|
0c7f23cdc9 | ||
|
|
669ed25e97 | ||
|
|
5c59dce71d | ||
|
|
8a5ef62d2a |
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* text=auto eol=lf
|
||||
9
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/AudioQnA/ sihan.chen@intel.com
|
||||
/ChatQnA/ liang1.lv@intel.com
|
||||
/CodeGen/ liang1.lv@intel.com
|
||||
/CodeTrans/ sihan.chen@intel.com
|
||||
/DocSum/ sihan.chen@intel.com
|
||||
/FaqGen/ letong.han@intel.com
|
||||
/SearchQnA/ letong.han@intel.com
|
||||
/Translation/ liang1.lv@intel.com
|
||||
/VisualQnA/ liang1.lv@intel.com
|
||||
1
.github/pull_request_template.md
vendored
@@ -13,6 +13,7 @@ List the type of change like below. Please delete options that are not relevant.
|
||||
- [ ] Bug fix (non-breaking change which fixes an issue)
|
||||
- [ ] New feature (non-breaking change which adds new functionality)
|
||||
- [ ] Breaking change (fix or feature that would break existing design and interface)
|
||||
- [ ] Others (enhancement, documentation, validation, etc.)
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
||||
106
.github/workflows/E2E_test_with_compose.yml
vendored
@@ -1,106 +0,0 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: E2E test with docker compose
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- "**/docker/**"
|
||||
- "**/tests/**"
|
||||
- "**/ui/**"
|
||||
- "!**.md"
|
||||
- "!**.txt"
|
||||
- .github/workflows/E2E_test_with_compose.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:
|
||||
job1:
|
||||
name: Get-test-matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
run_matrix: ${{ steps.get-test-matrix.outputs.run_matrix }}
|
||||
steps:
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: "refs/pull/${{ github.event.number }}/merge"
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get test matrix
|
||||
id: get-test-matrix
|
||||
run: |
|
||||
set -xe
|
||||
merged_commit=$(git log -1 --format='%H')
|
||||
changed_files=$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${merged_commit} | \
|
||||
grep -vE '.github|README.md|*.txt|deprecate|kubernetes|manifest')
|
||||
examples=$(printf '%s\n' "${changed_files[@]}" | grep '/' | cut -d'/' -f1 | sort -u)
|
||||
run_matrix="{\"include\":["
|
||||
for example in ${examples}; do
|
||||
run_hardware=""
|
||||
if [ $(printf '%s\n' "${changed_files[@]}" | grep ${example} | grep -c gaudi) != 0 ]; then run_hardware="gaudi"; fi
|
||||
if [ $(printf '%s\n' "${changed_files[@]}" | grep ${example} | grep -c xeon) != 0 ]; then run_hardware="xeon ${run_hardware}"; fi
|
||||
if [ "$run_hardware" = "" ]; then run_hardware="xeon"; fi
|
||||
for hw in ${run_hardware}; do
|
||||
run_matrix="${run_matrix}{\"example\":\"${example}\",\"hardware\":\"${hw}\"},"
|
||||
done
|
||||
done
|
||||
run_matrix=$run_matrix"]}"
|
||||
echo "run_matrix=${run_matrix}" >> $GITHUB_OUTPUT
|
||||
|
||||
Example-test:
|
||||
needs: job1
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.job1.outputs.run_matrix) }}
|
||||
runs-on: ${{ matrix.hardware }}
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Test example
|
||||
run: |
|
||||
echo "Matrix - example ${{ matrix.example }}, hardware ${{ matrix.hardware }}"
|
||||
|
||||
- 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 }}
|
||||
example: ${{ matrix.example }}
|
||||
hardware: ${{ matrix.hardware }}
|
||||
run: |
|
||||
cd ${{ github.workspace }}/$example/tests
|
||||
example_l=$(echo $example | tr '[:upper:]' '[:lower:]')
|
||||
if [ -f test_${example_l}_on_${hardware}.sh ]; then timeout 30m bash test_${example_l}_on_${hardware}.sh; else echo "Test script not found, skip test!"; fi
|
||||
|
||||
- name: Clean up container
|
||||
env:
|
||||
example: ${{ matrix.example }}
|
||||
hardware: ${{ matrix.hardware }}
|
||||
if: cancelled() || failure()
|
||||
run: |
|
||||
cd ${{ github.workspace }}/$example/docker/$hardware
|
||||
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
|
||||
echo y | docker system prune
|
||||
|
||||
- name: Publish pipeline artifact
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.example }}-${{ matrix.hardware }}
|
||||
path: ${{ github.workspace }}/${{ matrix.example }}/tests/*.log
|
||||
166
.github/workflows/_example-workflow.yml
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Example jobs
|
||||
permissions: read-all
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
node:
|
||||
required: true
|
||||
type: string
|
||||
example:
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
default: "latest"
|
||||
required: false
|
||||
type: string
|
||||
build:
|
||||
default: true
|
||||
required: false
|
||||
type: boolean
|
||||
scan:
|
||||
default: true
|
||||
required: false
|
||||
type: boolean
|
||||
test_compose:
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
test_k8s:
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
test_gmc:
|
||||
default: false
|
||||
required: false
|
||||
type: boolean
|
||||
opea_branch:
|
||||
default: "main"
|
||||
required: false
|
||||
type: string
|
||||
jobs:
|
||||
####################################################################################################
|
||||
# Image Build
|
||||
####################################################################################################
|
||||
build-images:
|
||||
runs-on: "docker-build-${{ inputs.node }}"
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Clone required Repo
|
||||
run: |
|
||||
cd ${{ github.workspace }}/${{ inputs.example }}/docker
|
||||
docker_compose_path=${{ github.workspace }}/${{ inputs.example }}/docker/docker_build_compose.yaml
|
||||
if [[ $(grep -c "tei-gaudi:" ${docker_compose_path}) != 0 ]]; then
|
||||
git clone https://github.com/huggingface/tei-gaudi.git
|
||||
fi
|
||||
if [[ $(grep -c "vllm:" ${docker_compose_path}) != 0 ]]; then
|
||||
git clone https://github.com/vllm-project/vllm.git
|
||||
fi
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
cd GenAIComps && git checkout ${{ inputs.opea_branch }} && cd ../
|
||||
|
||||
- name: Build Image
|
||||
if: ${{ fromJSON(inputs.build) }}
|
||||
uses: opea-project/validation/actions/image-build@main
|
||||
with:
|
||||
work_dir: ${{ github.workspace }}/${{ inputs.example }}/docker
|
||||
docker_compose_path: ${{ github.workspace }}/${{ inputs.example }}/docker/docker_build_compose.yaml
|
||||
registry: ${OPEA_IMAGE_REPO}opea
|
||||
tag: ${{ inputs.tag }}
|
||||
|
||||
####################################################################################################
|
||||
# Trivy Scan
|
||||
####################################################################################################
|
||||
get-image-list:
|
||||
needs: [build-images]
|
||||
if: ${{ fromJSON(inputs.scan) && inputs.node == 'gaudi' }}
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.scan-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set Matrix
|
||||
id: scan-matrix
|
||||
run: |
|
||||
pip install yq
|
||||
compose_path=${{ github.workspace }}/${{ inputs.example }}/docker/docker_build_compose.yaml
|
||||
echo "matrix=$(cat ${compose_path} | yq -r '.[]' | jq 'keys' | jq -c '.')" >> $GITHUB_OUTPUT
|
||||
|
||||
scan-images:
|
||||
needs: [get-image-list, build-images]
|
||||
if: ${{ fromJSON(inputs.scan) && inputs.node == 'gaudi'}}
|
||||
runs-on: "docker-build-${{ inputs.node }}"
|
||||
strategy:
|
||||
matrix:
|
||||
image: ${{ fromJSON(needs.get-image-list.outputs.matrix) }}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Pull Image
|
||||
run: |
|
||||
docker pull ${OPEA_IMAGE_REPO}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
echo "OPEA_IMAGE_REPO=${OPEA_IMAGE_REPO}" >> $GITHUB_ENV
|
||||
|
||||
- name: Scan Container
|
||||
uses: opea-project/validation/actions/trivy-scan@main
|
||||
with:
|
||||
image-ref: ${{ env.OPEA_IMAGE_REPO }}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
output: ${{ matrix.image }}-scan.txt
|
||||
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: docker rmi -f ${OPEA_IMAGE_REPO}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
|
||||
- uses: actions/upload-artifact@v4.3.4
|
||||
with:
|
||||
name: ${{ matrix.image }}-scan
|
||||
path: ${{ matrix.image }}-scan.txt
|
||||
overwrite: true
|
||||
|
||||
####################################################################################################
|
||||
# Docker Compose Test
|
||||
####################################################################################################
|
||||
test-example-compose:
|
||||
needs: [build-images]
|
||||
if: ${{ fromJSON(inputs.test_compose) }}
|
||||
uses: ./.github/workflows/_run-docker-compose.yml
|
||||
with:
|
||||
tag: ${{ inputs.tag }}
|
||||
example: ${{ inputs.example }}
|
||||
hardware: ${{ inputs.node }}
|
||||
secrets: inherit
|
||||
|
||||
|
||||
####################################################################################################
|
||||
# K8S Test
|
||||
####################################################################################################
|
||||
test-k8s-manifest:
|
||||
needs: [build-images]
|
||||
if: ${{ fromJSON(inputs.test_k8s) }}
|
||||
uses: ./.github/workflows/_manifest-e2e.yml
|
||||
with:
|
||||
example: ${{ inputs.example }}
|
||||
hardware: ${{ inputs.node }}
|
||||
tag: ${{ inputs.tag }}
|
||||
context: "CD"
|
||||
secrets: inherit
|
||||
|
||||
####################################################################################################
|
||||
# GMC Test
|
||||
####################################################################################################
|
||||
test-gmc-pipeline:
|
||||
needs: [build-images]
|
||||
if: ${{ fromJSON(inputs.test_gmc) }}
|
||||
uses: ./.github/workflows/_gmc-e2e.yml
|
||||
with:
|
||||
example: ${{ inputs.example }}
|
||||
hardware: ${{ inputs.node }}
|
||||
secrets: inherit
|
||||
80
.github/workflows/_get-test-matrix.yml
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Support push and pull_request events
|
||||
name: Get Test Matrix
|
||||
permissions: read-all
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
diff_excluded_files:
|
||||
required: false
|
||||
type: string
|
||||
default: '.github|README.md|*.txt'
|
||||
xeon_server_label:
|
||||
required: false
|
||||
type: string
|
||||
default: 'xeon'
|
||||
gaudi_server_label:
|
||||
required: false
|
||||
type: string
|
||||
default: 'gaudi'
|
||||
outputs:
|
||||
run_matrix:
|
||||
description: "The matrix string"
|
||||
value: ${{ jobs.job1.outputs.run_matrix }}
|
||||
|
||||
jobs:
|
||||
job1:
|
||||
name: Get-test-matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
run_matrix: ${{ steps.get-test-matrix.outputs.run_matrix }}
|
||||
steps:
|
||||
- name: Get checkout ref
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "pull_request" ] || [ "${{ github.event_name }}" == "pull_request_target" ]; then
|
||||
echo "CHECKOUT_REF=refs/pull/${{ github.event.number }}/merge" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "checkout ref ${{ env.CHECKOUT_REF }}"
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get test matrix
|
||||
id: get-test-matrix
|
||||
run: |
|
||||
set -xe
|
||||
if [ "${{ github.event_name }}" == "pull_request" ] || [ "${{ github.event_name }}" == "pull_request_target" ]; then
|
||||
LATEST_COMMIT_SHA=$(curl -H "Authorization: token ${{ secrets.GITHUB_TOKEN }}" \
|
||||
"https://api.github.com/repos/opea-project/GenAIExamples/commits?sha=main" | jq -r '.[0].sha')
|
||||
echo "Latest commit SHA is $LATEST_COMMIT_SHA"
|
||||
base_commit=$LATEST_COMMIT_SHA
|
||||
else
|
||||
base_commit=$(git rev-parse HEAD~1) # push event
|
||||
fi
|
||||
merged_commit=$(git log -1 --format='%H')
|
||||
changed_files="$(git diff --name-only ${base_commit} ${merged_commit} | \
|
||||
grep -vE '${{ inputs.diff_excluded_files }}')" || true
|
||||
examples=$(printf '%s\n' "${changed_files[@]}" | grep '/' | cut -d'/' -f1 | sort -u)
|
||||
run_matrix="{\"include\":["
|
||||
for example in ${examples}; do
|
||||
run_hardware=""
|
||||
if [ $(printf '%s\n' "${changed_files[@]}" | grep ${example} | grep -c gaudi) != 0 ]; then run_hardware="gaudi"; fi
|
||||
if [ $(printf '%s\n' "${changed_files[@]}" | grep ${example} | grep -c xeon) != 0 ]; then run_hardware="xeon ${run_hardware}"; fi
|
||||
if [ "$run_hardware" == "" ]; then run_hardware="gaudi"; fi
|
||||
for hw in ${run_hardware}; do
|
||||
if [ "$hw" == "gaudi" ] && [ "${{ inputs.gaudi_server_label }}" != "" ]; then
|
||||
run_matrix="${run_matrix}{\"example\":\"${example}\",\"hardware\":\"${{ inputs.gaudi_server_label }}\"},"
|
||||
elif [ "${{ inputs.xeon_server_label }}" != "" ]; then
|
||||
run_matrix="${run_matrix}{\"example\":\"${example}\",\"hardware\":\"${{ inputs.xeon_server_label }}\"},"
|
||||
fi
|
||||
done
|
||||
done
|
||||
run_matrix=$run_matrix"]}"
|
||||
echo "run_matrix=${run_matrix}" >> $GITHUB_OUTPUT
|
||||
87
.github/workflows/_gmc-e2e.yml
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# This workflow will only test GMC pipeline and will not install GMC any more
|
||||
name: Single GMC E2e Test For CD Workflow Call
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
example:
|
||||
default: "ChatQnA"
|
||||
description: "The example to test on K8s"
|
||||
required: true
|
||||
type: string
|
||||
hardware:
|
||||
default: "xeon"
|
||||
description: "Nodes to run the test, xeon or gaudi"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
gmc-test:
|
||||
runs-on: "k8s-${{ inputs.hardware }}"
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Get checkout ref
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "pull_request" ] || [ "${{ github.event_name }}" == "pull_request_target" ]; then
|
||||
echo "CHECKOUT_REF=refs/pull/${{ github.event.number }}/merge" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "checkout ref ${{ env.CHECKOUT_REF }}"
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set variables
|
||||
run: |
|
||||
echo "IMAGE_REPO=$OPEA_IMAGE_REPO" >> $GITHUB_ENV
|
||||
lower_example=$(echo "${{ inputs.example }}" | tr '[:upper:]' '[:lower:]')
|
||||
echo "APP_NAMESPACE=$lower_example-$(tr -dc a-z0-9 </dev/urandom | head -c 16)" >> $GITHUB_ENV
|
||||
echo "ROLLOUT_TIMEOUT_SECONDS=1800s" >> $GITHUB_ENV
|
||||
echo "KUBECTL_TIMEOUT_SECONDS=60s" >> $GITHUB_ENV
|
||||
echo "continue_test=true" >> $GITHUB_ENV
|
||||
echo "should_cleanup=false" >> $GITHUB_ENV
|
||||
echo "APP_NAMESPACE=$APP_NAMESPACE"
|
||||
|
||||
- name: Run tests
|
||||
id: run-test
|
||||
env:
|
||||
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
|
||||
GOOGLE_CSE_ID: ${{ secrets.GOOGLE_CSE_ID }}
|
||||
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
||||
run: |
|
||||
if [[ ! -f ${{ github.workspace }}/${{ inputs.example }}/tests/test_gmc_on_${{ inputs.hardware }}.sh ]]; then
|
||||
echo "No test script found, exist test!"
|
||||
exit 0
|
||||
else
|
||||
echo "should_cleanup=true" >> $GITHUB_ENV
|
||||
${{ github.workspace }}/${{ inputs.example }}/tests/test_gmc_on_${{ inputs.hardware }}.sh install_${{ inputs.example }}
|
||||
echo "Testing ${{ inputs.example }}, waiting for pod ready..."
|
||||
if kubectl rollout status deployment --namespace "$APP_NAMESPACE" --timeout "$ROLLOUT_TIMEOUT_SECONDS"; then
|
||||
echo "Testing gmc ${{ inputs.example }}, running validation test..."
|
||||
${{ github.workspace }}/${{ inputs.example }}/tests/test_gmc_on_${{ inputs.hardware }}.sh validate_${{ inputs.example }}
|
||||
else
|
||||
echo "Timeout waiting for pods in namespace $APP_NAMESPACE to be ready!"
|
||||
exit 1
|
||||
fi
|
||||
sleep 60
|
||||
fi
|
||||
|
||||
- name: Kubectl uninstall
|
||||
if: always()
|
||||
run: |
|
||||
if $should_cleanup; then
|
||||
if ! kubectl delete ns $APP_NAMESPACE --timeout=$KUBECTL_TIMEOUT_SECONDS; then
|
||||
kubectl delete pods --namespace $APP_NAMESPACE --force --grace-period=0 --all
|
||||
kubectl delete ns $APP_NAMESPACE --force --grace-period=0 --timeout=$KUBECTL_TIMEOUT_SECONDS
|
||||
fi
|
||||
fi
|
||||
146
.github/workflows/_gmc-workflow.yml
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Build and deploy GMC system on call and manual
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
default: "latest"
|
||||
required: true
|
||||
type: string
|
||||
description: "Tag to apply to images"
|
||||
node:
|
||||
default: "xeon"
|
||||
required: true
|
||||
type: string
|
||||
description: "Hardware to run test"
|
||||
opea_branch:
|
||||
default: "main"
|
||||
required: false
|
||||
type: string
|
||||
description: 'OPEA branch for image build'
|
||||
workflow_call:
|
||||
inputs:
|
||||
tag:
|
||||
default: "latest"
|
||||
required: true
|
||||
type: string
|
||||
description: "Tag to apply to images"
|
||||
node:
|
||||
default: "xeon"
|
||||
required: true
|
||||
type: string
|
||||
description: "Hardware to run test"
|
||||
opea_branch:
|
||||
default: "main"
|
||||
required: false
|
||||
type: string
|
||||
description: 'OPEA branch for image build'
|
||||
|
||||
jobs:
|
||||
####################################################################################################
|
||||
# Image Build and Scan
|
||||
####################################################################################################
|
||||
image-build:
|
||||
runs-on: "docker-build-${{ inputs.node }}"
|
||||
steps:
|
||||
- name: Checkout GenAIInfra repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: opea-project/GenAIInfra
|
||||
ref: ${{ inputs.opea_branch }}
|
||||
path: GenAIInfra
|
||||
|
||||
- name: Set variables
|
||||
id: set_variables
|
||||
run: |
|
||||
echo "DOCKER_REGISTRY=${OPEA_IMAGE_REPO}opea" >> $GITHUB_ENV
|
||||
echo "IMAGE_REPO=${OPEA_IMAGE_REPO}" >> $GITHUB_OUTPUT
|
||||
echo "VERSION=${{ inputs.tag }}" >> $GITHUB_ENV
|
||||
echo "VERSION=${{ inputs.tag }}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Build image and push
|
||||
run: |
|
||||
cd ${{github.workspace}}/GenAIInfra/microservices-connector
|
||||
make docker.build
|
||||
make docker.push
|
||||
|
||||
- name: Scan gmcmanager
|
||||
if: ${{ inputs.node == 'gaudi' }}
|
||||
uses: opea-project/validation/actions/trivy-scan@main
|
||||
with:
|
||||
image-ref: ${{ env.DOCKER_REGISTRY }}/gmcmanager:${{ env.VERSION }}
|
||||
output: gmcmanager-scan.txt
|
||||
|
||||
- name: Upload gmcmanager scan result
|
||||
if: ${{ inputs.node == 'gaudi' }}
|
||||
uses: actions/upload-artifact@v4.3.4
|
||||
with:
|
||||
name: gmcmanager-scan
|
||||
path: gmcmanager-scan.txt
|
||||
overwrite: true
|
||||
|
||||
- name: Scan gmcrouter
|
||||
if: ${{ inputs.node == 'gaudi' }}
|
||||
uses: opea-project/validation/actions/trivy-scan@main
|
||||
with:
|
||||
image-ref: ${{ env.DOCKER_REGISTRY }}/gmcrouter:${{ env.VERSION }}
|
||||
output: gmcrouter-scan.txt
|
||||
|
||||
- name: Upload gmcrouter scan result
|
||||
if: ${{ inputs.node == 'gaudi' }}
|
||||
uses: actions/upload-artifact@v4.3.4
|
||||
with:
|
||||
name: gmcrouter-scan
|
||||
path: gmcrouter-scan.txt
|
||||
overwrite: true
|
||||
|
||||
- name: Clean up images
|
||||
if: always()
|
||||
run: |
|
||||
docker rmi ${{ env.DOCKER_REGISTRY }}/gmcrouter:${{ env.VERSION }}
|
||||
docker rmi ${{ env.DOCKER_REGISTRY }}/gmcmanager:${{ env.VERSION }}
|
||||
|
||||
- name: Clean up GenAIInfra source codes
|
||||
if: always()
|
||||
run: |
|
||||
rm -rf ${{github.workspace}}/GenAIInfra
|
||||
|
||||
####################################################################################################
|
||||
# GMC Install
|
||||
####################################################################################################
|
||||
gmc-install:
|
||||
needs: image-build
|
||||
runs-on: "k8s-${{ inputs.node }}"
|
||||
steps:
|
||||
- name: Checkout GenAIInfra repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: opea-project/GenAIInfra
|
||||
ref: ${{ inputs.opea_branch }}
|
||||
path: GenAIInfra
|
||||
|
||||
- name: Set variables
|
||||
run: |
|
||||
echo "SYSTEM_NAMESPACE=opea-system" >> $GITHUB_ENV
|
||||
echo "VERSION=${{ inputs.tag }}" >> $GITHUB_ENV
|
||||
echo "SET_VERSION=true" >> $GITHUB_ENV # to change the tag of microservice images
|
||||
|
||||
- name: Cleanup existing GMC
|
||||
run: |
|
||||
cd GenAIInfra
|
||||
.github/workflows/scripts/e2e/gmc_install.sh cleanup_gmc
|
||||
cd ..
|
||||
|
||||
- name: Install GMC
|
||||
run: |
|
||||
cd GenAIInfra
|
||||
.github/workflows/scripts/e2e/gmc_install.sh install_gmc
|
||||
cd ..
|
||||
|
||||
- name: Clean up GenAIInfra source codes
|
||||
if: always()
|
||||
run: |
|
||||
rm -rf ${{github.workspace}}/GenAIInfra
|
||||
69
.github/workflows/_image-build.yml
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Image Build
|
||||
permissions: read-all
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
image_repo:
|
||||
required: false
|
||||
type: string
|
||||
image_tag:
|
||||
required: true
|
||||
type: string
|
||||
mega_service:
|
||||
required: true
|
||||
type: string
|
||||
runner_label:
|
||||
required: false
|
||||
type: string
|
||||
default: 'docker-build-xeon'
|
||||
outputs:
|
||||
image_repo:
|
||||
description: "The image repository used for the image build"
|
||||
value: ${{ jobs.mega-image-build.outputs.image_repo }}
|
||||
image_tag:
|
||||
description: "The image tag used for the image build"
|
||||
value: ${{ jobs.mega-image-build.outputs.image_tag }}
|
||||
|
||||
jobs:
|
||||
mega-image-build:
|
||||
runs-on: ${{ inputs.runner_label }}
|
||||
outputs:
|
||||
image_repo: ${{ steps.build-megaservice-image.outputs.image_repo }}
|
||||
image_tag: ${{ steps.build-megaservice-image.outputs.image_tag }}
|
||||
steps:
|
||||
- name: Clean up Working Directory
|
||||
run: |
|
||||
sudo rm -rf ${{github.workspace}}/* || true
|
||||
|
||||
- name: Get checkout ref
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "pull_request" ] || [ "${{ github.event_name }}" == "pull_request_target" ]; then
|
||||
echo "CHECKOUT_REF=refs/pull/${{ github.event.number }}/merge" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "checkout ref ${{ env.CHECKOUT_REF }}"
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Building MegaService Docker Image
|
||||
id: build-megaservice-image
|
||||
env:
|
||||
IMAGE_REPO: ${{ inputs.image_repo }}
|
||||
IMAGE_TAG: ${{ inputs.image_tag }}
|
||||
MEGA_SERVICE: ${{ inputs.mega_service }}
|
||||
run: |
|
||||
.github/workflows/scripts/build_push.sh ${{ env.MEGA_SERVICE}}
|
||||
if [ -z "${{ env.IMAGE_REPO }}" ]; then
|
||||
IMAGE_REPO=$OPEA_IMAGE_REPO
|
||||
fi
|
||||
echo "IMAGE_TAG=${IMAGE_TAG}"
|
||||
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
|
||||
echo "image_repo=${IMAGE_REPO}" >> $GITHUB_OUTPUT
|
||||
105
.github/workflows/_manifest-e2e.yml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Single Kubernetes Manifest E2e Test For Call
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
example:
|
||||
default: "ChatQnA"
|
||||
description: "The example to test on K8s"
|
||||
required: true
|
||||
type: string
|
||||
hardware:
|
||||
default: "xeon"
|
||||
description: "Nodes to run the test, xeon or gaudi"
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
default: "latest"
|
||||
description: "Tag to apply to images, default is latest"
|
||||
required: false
|
||||
type: string
|
||||
context:
|
||||
default: "CI"
|
||||
description: "CI or CD"
|
||||
required: false
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
manifest-test:
|
||||
runs-on: "k8s-${{ inputs.hardware }}"
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Get checkout ref
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "pull_request" ] || [ "${{ github.event_name }}" == "pull_request_target" ]; then
|
||||
echo "CHECKOUT_REF=refs/pull/${{ github.event.number }}/merge" >> $GITHUB_ENV
|
||||
else
|
||||
echo "CHECKOUT_REF=${{ github.ref }}" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "checkout ref ${{ env.CHECKOUT_REF }}"
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ env.CHECKOUT_REF }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set variables
|
||||
run: |
|
||||
echo "IMAGE_REPO=$OPEA_IMAGE_REPO" >> $GITHUB_ENV
|
||||
echo "IMAGE_TAG=${{ inputs.tag }}" >> $GITHUB_ENV
|
||||
lower_example=$(echo "${{ inputs.example }}" | tr '[:upper:]' '[:lower:]')
|
||||
echo "NAMESPACE=$lower_example-$(tr -dc a-z0-9 </dev/urandom | head -c 16)" >> $GITHUB_ENV
|
||||
echo "ROLLOUT_TIMEOUT_SECONDS=1800s" >> $GITHUB_ENV
|
||||
echo "KUBECTL_TIMEOUT_SECONDS=60s" >> $GITHUB_ENV
|
||||
echo "continue_test=true" >> $GITHUB_ENV
|
||||
echo "should_cleanup=false" >> $GITHUB_ENV
|
||||
echo "skip_validate=true" >> $GITHUB_ENV
|
||||
echo "CONTEXT=${{ inputs.context }}" >> $GITHUB_ENV
|
||||
echo "NAMESPACE=$NAMESPACE"
|
||||
|
||||
- name: Kubectl install
|
||||
id: install
|
||||
run: |
|
||||
if [[ ! -f ${{ github.workspace }}/${{ inputs.example }}/tests/test_manifest_on_${{ inputs.hardware }}.sh ]]; then
|
||||
echo "No test script found, exist test!"
|
||||
exit 0
|
||||
else
|
||||
${{ github.workspace }}/${{ inputs.example }}/tests/test_manifest_on_${{ inputs.hardware }}.sh init_${{ inputs.example }}
|
||||
echo "should_cleanup=true" >> $GITHUB_ENV
|
||||
kubectl create ns $NAMESPACE
|
||||
${{ github.workspace }}/${{ inputs.example }}/tests/test_manifest_on_${{ inputs.hardware }}.sh install_${{ inputs.example }} $NAMESPACE
|
||||
echo "Testing ${{ inputs.example }}, waiting for pod ready..."
|
||||
if kubectl rollout status deployment --namespace "$NAMESPACE" --timeout "$ROLLOUT_TIMEOUT_SECONDS"; then
|
||||
echo "Testing manifests ${{ inputs.example }}, waiting for pod ready done!"
|
||||
echo "skip_validate=false" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Timeout waiting for pods in namespace $NAMESPACE to be ready!"
|
||||
exit 1
|
||||
fi
|
||||
sleep 60
|
||||
fi
|
||||
|
||||
- name: Validate e2e test
|
||||
if: always()
|
||||
run: |
|
||||
if $skip_validate; then
|
||||
echo "Skip validate"
|
||||
else
|
||||
${{ github.workspace }}/${{ inputs.example }}/tests/test_manifest_on_${{ inputs.hardware }}.sh validate_${{ inputs.example }} $NAMESPACE
|
||||
fi
|
||||
|
||||
- name: Kubectl uninstall
|
||||
if: always()
|
||||
run: |
|
||||
if $should_cleanup; then
|
||||
if ! kubectl delete ns $NAMESPACE --timeout=$KUBECTL_TIMEOUT_SECONDS; then
|
||||
kubectl delete pods --namespace $NAMESPACE --force --grace-period=0 --all
|
||||
kubectl delete ns $NAMESPACE --force --grace-period=0 --timeout=$KUBECTL_TIMEOUT_SECONDS
|
||||
fi
|
||||
fi
|
||||
117
.github/workflows/_run-docker-compose.yml
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Image Build
|
||||
permissions: read-all
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
registry:
|
||||
description: Container Registry URL
|
||||
required: false
|
||||
default: ""
|
||||
type: string
|
||||
tag:
|
||||
description: Container Tag
|
||||
required: false
|
||||
default: "latest"
|
||||
type: string
|
||||
example:
|
||||
description: Example to test
|
||||
required: true
|
||||
type: string
|
||||
hardware:
|
||||
description: Hardware to run the test on
|
||||
required: true
|
||||
type: string
|
||||
jobs:
|
||||
get-test-case:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
test_cases: ${{ steps.test-case-matrix.outputs.test_cases }}
|
||||
CHECKOUT_REF: ${{ steps.get-checkout-ref.outputs.CHECKOUT_REF }}
|
||||
steps:
|
||||
- name: Get checkout ref
|
||||
id: get-checkout-ref
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" == "pull_request" ] || [ "${{ github.event_name }}" == "pull_request_target" ]; then
|
||||
CHECKOUT_REF=refs/pull/${{ github.event.number }}/merge
|
||||
else
|
||||
CHECKOUT_REF=${{ github.ref }}
|
||||
fi
|
||||
echo "CHECKOUT_REF=${CHECKOUT_REF}" >> $GITHUB_OUTPUT
|
||||
echo "checkout ref ${CHECKOUT_REF}"
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ steps.get-checkout-ref.outputs.CHECKOUT_REF }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get test matrix
|
||||
shell: bash
|
||||
id: test-case-matrix
|
||||
run: |
|
||||
set -x
|
||||
example_l=$(echo ${{ inputs.example }} | tr '[:upper:]' '[:lower:]')
|
||||
cd ${{ github.workspace }}/${{ inputs.example }}/tests
|
||||
test_cases=$(find . -type f -name "test_${example_l}*on_${{ inputs.hardware }}.sh" -print | cut -d/ -f2 | jq -R '.' | jq -sc '.')
|
||||
echo "test_cases=$test_cases" >> $GITHUB_OUTPUT
|
||||
|
||||
run-test:
|
||||
needs: [get-test-case]
|
||||
strategy:
|
||||
matrix:
|
||||
test_case: ${{ fromJSON(needs.get-test-case.outputs.test_cases) }}
|
||||
fail-fast: false
|
||||
runs-on: ${{ inputs.hardware }}
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Clean up Working Directory
|
||||
run: |
|
||||
sudo rm -rf ${{github.workspace}}/* || true
|
||||
docker system prune -f
|
||||
docker rmi $(docker images --filter reference="*/*/*:latest" -q) || true
|
||||
docker rmi $(docker images --filter reference="*/*:ci" -q) || true
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: ${{ needs.get-test-case.outputs.CHECKOUT_REF }}
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Run test
|
||||
shell: bash
|
||||
env:
|
||||
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
|
||||
GOOGLE_CSE_ID: ${{ secrets.GOOGLE_CSE_ID }}
|
||||
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
||||
PINECONE_KEY: ${{ secrets.PINECONE_KEY }}
|
||||
IMAGE_REPO: ${{ inputs.registry }}
|
||||
IMAGE_TAG: ${{ inputs.tag }}
|
||||
example: ${{ inputs.example }}
|
||||
hardware: ${{ inputs.hardware }}
|
||||
test_case: ${{ matrix.test_case }}
|
||||
run: |
|
||||
cd ${{ github.workspace }}/$example/tests
|
||||
if [[ "$IMAGE_REPO" == "" ]]; then export IMAGE_REPO="${OPEA_IMAGE_REPO}opea"; fi
|
||||
if [ -f ${test_case} ]; then timeout 30m bash ${test_case}; else echo "Test script {${test_case}} not found, skip test!"; fi
|
||||
|
||||
- name: Clean up container
|
||||
shell: bash
|
||||
if: cancelled() || failure()
|
||||
run: |
|
||||
cd ${{ github.workspace }}/${{ inputs.example }}/docker/${{ inputs.hardware }}
|
||||
yaml_files=$(find . -type f -name "*compose*yaml")
|
||||
for file in $yaml_files; do
|
||||
docker compose -f ${file} stop && docker compose -f ${file} rm -f || true
|
||||
done
|
||||
docker system prune -f
|
||||
docker rmi $(docker images --filter reference="*:5000/*/*" -q) || true
|
||||
|
||||
- name: Publish pipeline artifact
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: ${{ matrix.test_case }}
|
||||
path: ${{ github.workspace }}/${{ inputs.example }}/tests/*.log
|
||||
78
.github/workflows/chatqna_benchmark.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: benchmark test with chatqna_benchmark
|
||||
|
||||
on:
|
||||
# pull_request:
|
||||
# branches: [main]
|
||||
# types: [opened, reopened, ready_for_review, synchronize]
|
||||
# # inputs:
|
||||
# # variables:
|
||||
# # hardware:
|
||||
# # description: 'Enter your param' #gaudi or xeon
|
||||
# # required: true
|
||||
# # default: xeon
|
||||
schedule:
|
||||
- cron: "35 0 * * 6"
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
hardware:
|
||||
description: 'Enter your hardware' #gaudi or xeon
|
||||
required: true
|
||||
default: gaudi
|
||||
|
||||
jobs:
|
||||
Example-test:
|
||||
runs-on: ${{ github.event.inputs.hardware || 'gaudi' }} #xeon #gaudi
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Clone repo GenAIEval
|
||||
run: |
|
||||
git clone https://github.com/opea-project/GenAIEval.git
|
||||
cd GenAIEval && git checkout v0.6
|
||||
|
||||
- name: Run test
|
||||
env:
|
||||
HUGGINGFACEHUB_API_TOKEN: ${{ secrets.HUGGINGFACEHUB_API_TOKEN }}
|
||||
GOOGLE_CSE_ID: ${{ secrets.GOOGLE_CSE_ID }}
|
||||
GOOGLE_API_KEY: ${{ secrets.GOOGLE_API_KEY }}
|
||||
hardware: ${{ github.event.inputs.hardware || 'gaudi' }} #xeon
|
||||
mode: perf
|
||||
IMAGE_TAG: latest
|
||||
IMAGE_REPO_GAUDI: ${{ vars.IMAGE_REPO_GAUDI }}
|
||||
IMAGE_REPO_XEON: ${{ vars.IMAGE_REPO_XEON }}
|
||||
run: |
|
||||
# cd ${{ github.workspace }}/$example/tests
|
||||
cd ${{ github.workspace }}/ChatQnA/tests
|
||||
cp ../../GenAIEval/evals/benchmark/chatqna_benchmark.py .
|
||||
cp ../../GenAIEval/evals/benchmark/data.json ${{ github.workspace }}/ChatQnA/docker/${hardware}/
|
||||
|
||||
if [ "$hardware" == "gaudi" ]; then IMAGE_REPO=$IMAGE_REPO_GAUDI; else IMAGE_REPO=$IMAGE_REPO_XEON; fi
|
||||
export IMAGE_REPO=${IMAGE_REPO}
|
||||
# example_l=$(echo $example | tr '[:upper:]' '[:lower:]')
|
||||
if [ -f test_chatqna_on_${hardware}.sh ]; then timeout 30m bash test_chatqna_on_${hardware}.sh > ${hardware}_output.log; else echo "Test script not found, skip test!"; fi
|
||||
|
||||
- name: Process log and save to JSON
|
||||
env:
|
||||
hardware: ${{ github.event.inputs.hardware || 'gaudi' }} #xeon
|
||||
run: |
|
||||
cd ${{ github.workspace }}/ChatQnA/tests
|
||||
echo '{}' > ${hardware}_output.json
|
||||
echo $(grep -a 'Total Requests:' ${hardware}_output.log | awk '{print "{\"total_requests\": \""$3 "\"}"}') > ${hardware}_output.json
|
||||
echo $(grep -a 'P50 latency is' ${hardware}_output.log | awk '{print "{\"p50_latency\": \""$4 "\"}"}') >> ${hardware}_output.json
|
||||
echo $(grep -a 'P99 latency is' ${hardware}_output.log | awk '{print "{\"p99_latency\": \""$4 "\"}"}') >> ${hardware}_output.json
|
||||
jq -s 'add' ${hardware}_output.json > ${hardware}_final_output.json && mv ${hardware}_final_output.json ${hardware}_output.json
|
||||
|
||||
- name: Publish pipeline artifact
|
||||
if: ${{ !cancelled() }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: |
|
||||
${{ github.workspace }}/ChatQnA/tests/*.log
|
||||
${{ github.workspace }}/ChatQnA/tests/*.json
|
||||
@@ -4,7 +4,7 @@
|
||||
ARG UBUNTU_VER=22.04
|
||||
FROM ubuntu:${UBUNTU_VER} as devel
|
||||
|
||||
ENV LANG C.UTF-8
|
||||
ENV LANG=C.UTF-8
|
||||
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends --fix-missing \
|
||||
aspell \
|
||||
|
||||
10
.github/workflows/docker/compose/AudioQnA-compose.yaml
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
audioqna:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/audioqna:${TAG:-latest}
|
||||
20
.github/workflows/docker/compose/ChatQnA-compose.yaml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
chatqna:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/chatqna:${TAG:-latest}
|
||||
chatqna-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: ${REGISTRY:-opea}/chatqna-ui:${TAG:-latest}
|
||||
chatqna-conversation-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile.react
|
||||
image: ${REGISTRY:-opea}/chatqna-conversation-ui:${TAG:-latest}
|
||||
20
.github/workflows/docker/compose/CodeGen-compose.yaml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
codegen:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/codegen:${TAG:-latest}
|
||||
codegen-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: ${REGISTRY:-opea}/codegen-ui:${TAG:-latest}
|
||||
codegen-react-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile.react
|
||||
image: ${REGISTRY:-opea}/codegen-conversation-ui:${TAG:-latest}
|
||||
15
.github/workflows/docker/compose/CodeTrans-compose.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
codetrans:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/codetrans:${TAG:-latest}
|
||||
codetrans-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: ${REGISTRY:-opea}/codetrans-ui:${TAG:-latest}
|
||||
20
.github/workflows/docker/compose/DocSum-compose.yaml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
docsum:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/docsum:${TAG:-latest}
|
||||
docsum-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: ${REGISTRY:-opea}/docsum-ui:${TAG:-latest}
|
||||
docsum-react-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile.react
|
||||
image: ${REGISTRY:-opea}/docsum-react-ui:${TAG:-latest}
|
||||
20
.github/workflows/docker/compose/FaqGen-compose.yaml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
faqgen:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/faqgen:${TAG:-latest}
|
||||
faqgen-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: ${REGISTRY:-opea}/faqgen-ui:${TAG:-latest}
|
||||
faqgen-react-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile.react
|
||||
image: ${REGISTRY:-opea}/faqgen-react-ui:${TAG:-latest}
|
||||
15
.github/workflows/docker/compose/SearchQnA-compose.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
searchqna:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/searchqna:${TAG:-latest}
|
||||
searchqna-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: ${REGISTRY:-opea}/searchqna-ui:${TAG:-latest}
|
||||
15
.github/workflows/docker/compose/Translation-compose.yaml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# this file should be run in the root of the repo
|
||||
services:
|
||||
translation:
|
||||
build:
|
||||
context: docker
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/translation:${TAG:-latest}
|
||||
translation-ui:
|
||||
build:
|
||||
context: docker/ui
|
||||
dockerfile: ./docker/Dockerfile
|
||||
image: ${REGISTRY:-opea}/translation-ui:${TAG:-latest}
|
||||
127
.github/workflows/manifest-e2e.yaml
vendored
@@ -1,127 +0,0 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: E2E test with manifests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- "**/kubernetes/manifests/**"
|
||||
- "**/tests/**"
|
||||
- "!**.md"
|
||||
- "!**.txt"
|
||||
- .github/workflows/manifest-e2e.yml
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
job1:
|
||||
name: Get-test-matrix
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
run_matrix: ${{ steps.get-test-matrix.outputs.run_matrix }}
|
||||
steps:
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get test matrix
|
||||
id: get-test-matrix
|
||||
run: |
|
||||
set -xe
|
||||
changed_files="$(git diff --name-only ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }} | \
|
||||
grep "/kubernetes/manifests/" | \
|
||||
grep -vE '.github|deprecated|docker')" || true
|
||||
examples=$(printf '%s\n' "${changed_files[@]}" | grep '/' | cut -d'/' -f1 | sort -u)
|
||||
run_matrix="{\"include\":["
|
||||
for example in ${examples}; do
|
||||
run_hardware=""
|
||||
if [ $(printf '%s\n' "${changed_files[@]}" | grep ${example} | grep -c gaudi) != 0 ]; then run_hardware="gaudi"; fi
|
||||
if [ $(printf '%s\n' "${changed_files[@]}" | grep ${example} | grep -c xeon) != 0 ]; then run_hardware="xeon ${run_hardware}"; fi
|
||||
if [[ -z "$run_hardware" ]]; then run_hardware="xeon"; fi
|
||||
for hw in ${run_hardware}; do
|
||||
if [ $hw = "gaudi" ]; then
|
||||
continue # skip gaudi for K8s test temporarily
|
||||
else
|
||||
#lower_example=$(echo "${example}" | tr '[:upper:]' '[:lower:]')
|
||||
run_matrix="${run_matrix}{\"example\":\"${example}\",\"hardware\":\"inspur-icx-1\"},"
|
||||
fi
|
||||
done
|
||||
done
|
||||
run_matrix=$run_matrix"]}"
|
||||
echo "run_matrix=${run_matrix}" >> $GITHUB_OUTPUT
|
||||
|
||||
manifest-test:
|
||||
needs: job1
|
||||
if: always() && ${{ needs.job1.outputs.run_matrix.include.length }} > 0
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.job1.outputs.run_matrix) }}
|
||||
runs-on: ${{ matrix.hardware }}
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: E2e test manifest
|
||||
run: |
|
||||
echo "Matrix - manifest: ${{ matrix.example }}"
|
||||
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set variables
|
||||
run: |
|
||||
lower_example=$(echo "${{ matrix.example }}" | tr '[:upper:]' '[:lower:]')
|
||||
echo "NAMESPACE=$lower_example-$(date +%Y%m%d%H%M%S)" >> $GITHUB_ENV
|
||||
echo "ROLLOUT_TIMEOUT_SECONDS=1800s" >> $GITHUB_ENV
|
||||
echo "KUBECTL_TIMEOUT_SECONDS=60s" >> $GITHUB_ENV
|
||||
echo "should_cleanup=false" >> $GITHUB_ENV
|
||||
echo "skip_validate=false" >> $GITHUB_ENV
|
||||
echo "NAMESPACE=$NAMESPACE"
|
||||
|
||||
- name: Initialize manifest testing
|
||||
run: |
|
||||
${{ github.workspace }}/${{ matrix.example }}/tests/test_manifest_on_xeon.sh init_${{ matrix.example }}
|
||||
|
||||
- name: Kubectl install
|
||||
id: install
|
||||
run: |
|
||||
echo "should_cleanup=true" >> $GITHUB_ENV
|
||||
kubectl create ns $NAMESPACE
|
||||
${{ github.workspace }}/${{ matrix.example }}/tests/test_manifest_on_xeon.sh install_${{ matrix.example }} $NAMESPACE
|
||||
echo "Testing ${{ matrix.example }}, waiting for pod ready..."
|
||||
if kubectl rollout status deployment --namespace "$NAMESPACE" --timeout "$ROLLOUT_TIMEOUT_SECONDS"; then
|
||||
echo "Testing manifests ${{ matrix.example }}, waiting for pod ready done!"
|
||||
else
|
||||
echo "Timeout waiting for pods in namespace $NAMESPACE to be ready!"
|
||||
echo "skip_validate=true" >> $GITHUB_ENV
|
||||
exit 1
|
||||
fi
|
||||
sleep 60
|
||||
|
||||
- name: Validate e2e test
|
||||
if: always()
|
||||
run: |
|
||||
if $skip_validate; then
|
||||
echo "Skip validate"
|
||||
else
|
||||
${{ github.workspace }}/${{ matrix.example }}/tests/test_manifest_on_xeon.sh validate_${{ matrix.example }} $NAMESPACE
|
||||
fi
|
||||
|
||||
- name: Kubectl uninstall
|
||||
if: always()
|
||||
run: |
|
||||
if $should_cleanup; then
|
||||
if ! kubectl delete ns $NAMESPACE --timeout=$KUBECTL_TIMEOUT_SECONDS; then
|
||||
kubectl delete pods --namespace $NAMESPACE --force --grace-period=0 --all
|
||||
kubectl delete ns $NAMESPACE --force --grace-period=0 --timeout=$KUBECTL_TIMEOUT_SECONDS
|
||||
fi
|
||||
fi
|
||||
86
.github/workflows/manual-bom-scan.yml
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Examples docker images BoM scan on manual event
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
node:
|
||||
default: "gaudi"
|
||||
description: "Hardware to run test"
|
||||
required: true
|
||||
type: string
|
||||
examples:
|
||||
default: "ChatQnA"
|
||||
description: 'List of examples to test [AudioQnA,ChatQnA,CodeGen,CodeTrans,DocSum,FaqGen,SearchQnA,Translation]'
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
default: "latest"
|
||||
description: "Tag to apply to images"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions: read-all
|
||||
jobs:
|
||||
get-image-list:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.scan-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set Matrix
|
||||
id: scan-matrix
|
||||
run: |
|
||||
pip install yq
|
||||
examples=($(echo ${{ inputs.examples }} | tr ',' ' '))
|
||||
image_list=[]
|
||||
for example in ${examples[@]}
|
||||
do
|
||||
images=$(cat ${{ github.workspace }}/${example}/docker/docker_build_compose.yaml | yq -r '.[]' | jq 'keys' | jq -c '.')
|
||||
image_list=$(echo ${image_list} | jq -s '.[0] + .[1] | unique' - <(echo ${images}))
|
||||
done
|
||||
echo "matrix=$(echo ${image_list} | jq -c '.')" >> $GITHUB_OUTPUT
|
||||
|
||||
scan-license:
|
||||
needs: get-image-list
|
||||
runs-on: "docker-build-${{ inputs.node }}"
|
||||
strategy:
|
||||
matrix:
|
||||
image: ${{ fromJson(needs.get-image-list.outputs.matrix) }}
|
||||
fail-fast: false
|
||||
steps:
|
||||
- name: Pull Image
|
||||
run: |
|
||||
docker pull ${OPEA_IMAGE_REPO}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
echo "OPEA_IMAGE_REPO=${OPEA_IMAGE_REPO}" >> $GITHUB_ENV
|
||||
|
||||
- name: SBOM Scan Container
|
||||
uses: anchore/sbom-action@v0.17.1
|
||||
with:
|
||||
image: ${{ env.OPEA_IMAGE_REPO }}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
output-file: ${{ matrix.image }}-sbom-scan.txt
|
||||
format: 'spdx-json'
|
||||
|
||||
- name: Security Scan Container
|
||||
uses: aquasecurity/trivy-action@0.24.0
|
||||
with:
|
||||
image-ref: ${{ env.OPEA_IMAGE_REPO }}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
output: ${{ matrix.image }}-trivy-scan.txt
|
||||
format: 'table'
|
||||
exit-code: '1'
|
||||
ignore-unfixed: true
|
||||
vuln-type: 'os,library'
|
||||
severity: 'CRITICAL,HIGH'
|
||||
|
||||
- name: Cleanup
|
||||
if: always()
|
||||
run: docker rmi -f ${OPEA_IMAGE_REPO}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
|
||||
- uses: actions/upload-artifact@v4.3.4
|
||||
with:
|
||||
name: ${{ matrix.image }}-scan
|
||||
path: ${{ matrix.image }}-*-scan.txt
|
||||
overwrite: true
|
||||
68
.github/workflows/manual-docker-publish.yml
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Examples publish docker image on manual event
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
nodes:
|
||||
default: "gaudi"
|
||||
description: "Hardware to run test"
|
||||
required: true
|
||||
type: string
|
||||
examples:
|
||||
default: "ChatQnA"
|
||||
description: 'List of examples to test [AudioQnA,ChatQnA,CodeGen,CodeTrans,DocSum,FaqGen,SearchQnA,Translation]'
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
default: "latest"
|
||||
description: "Tag to apply to images"
|
||||
required: true
|
||||
type: string
|
||||
publish:
|
||||
default: false
|
||||
description: 'Publish images to docker hub'
|
||||
required: false
|
||||
type: boolean
|
||||
publish_tags:
|
||||
default: "latest,v1.0"
|
||||
description: 'Tag list apply to publish images'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions: read-all
|
||||
jobs:
|
||||
get-image-list:
|
||||
runs-on: ${{ inputs.node }}
|
||||
outputs:
|
||||
matrix: ${{ steps.scan-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set Matrix
|
||||
id: scan-matrix
|
||||
run: |
|
||||
examples=($(echo ${{ inputs.examples }} | tr ',' ' '))
|
||||
image_list=[]
|
||||
for example in ${examples[@]}
|
||||
do
|
||||
images=$(cat ${{ github.workspace }}/${example}/docker/docker_build_compose.yaml | yq -r '.[]' | jq 'keys' | jq -c '.')
|
||||
image_list=$(echo ${image_list} | jq -s '.[0] + .[1] | unique' - <(echo ${images}))
|
||||
done
|
||||
echo "matrix=$(echo ${image_list} | jq -c '.')" >> $GITHUB_OUTPUT
|
||||
|
||||
publish:
|
||||
needs: [get-image-list]
|
||||
strategy:
|
||||
matrix:
|
||||
image: ${{ fromJSON(needs.get-image-list.outputs.matrix) }}
|
||||
runs-on: "docker-build-${{ inputs.node }}"
|
||||
steps:
|
||||
- name: Image Publish
|
||||
uses: opea-project/validation/actions/image-publish@main
|
||||
with:
|
||||
local_image_ref: ${OPEA_IMAGE_REPO}opea/${{ matrix.image }}:${{ inputs.tag }}
|
||||
image_name: opea/${{ matrix.image }}
|
||||
publish_tags: ${{ inputs.publish_tags }}
|
||||
110
.github/workflows/manual-example-workflow.yml
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Examples CD workflow on manual event
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
nodes:
|
||||
default: "gaudi,xeon"
|
||||
description: "Hardware to run test"
|
||||
required: true
|
||||
type: string
|
||||
examples:
|
||||
default: "ChatQnA"
|
||||
description: 'List of examples to test [AudioQnA,ChatQnA,CodeGen,CodeTrans,DocSum,FaqGen,SearchQnA,Translation]'
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
default: "latest"
|
||||
description: "Tag to apply to images"
|
||||
required: true
|
||||
type: string
|
||||
deploy_gmc:
|
||||
default: false
|
||||
description: 'Whether to deploy gmc'
|
||||
required: true
|
||||
type: boolean
|
||||
build:
|
||||
default: true
|
||||
description: 'Build test required images for Examples'
|
||||
required: false
|
||||
type: boolean
|
||||
scan:
|
||||
default: true
|
||||
description: 'Scan all images with Trivy'
|
||||
required: false
|
||||
type: boolean
|
||||
test_compose:
|
||||
default: true
|
||||
description: 'Test examples with docker compose'
|
||||
required: false
|
||||
type: boolean
|
||||
test_k8s:
|
||||
default: false
|
||||
description: 'Test examples with k8s'
|
||||
required: false
|
||||
type: boolean
|
||||
test_gmc:
|
||||
default: false
|
||||
description: 'Test examples with gmc'
|
||||
required: false
|
||||
type: boolean
|
||||
opea_branch:
|
||||
default: "main"
|
||||
description: 'OPEA branch for image build'
|
||||
required: false
|
||||
type: string
|
||||
|
||||
permissions: read-all
|
||||
jobs:
|
||||
get-test-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
examples: ${{ steps.get-matrix.outputs.examples }}
|
||||
nodes: ${{ steps.get-matrix.outputs.nodes }}
|
||||
steps:
|
||||
- name: Create Matrix
|
||||
id: get-matrix
|
||||
run: |
|
||||
examples=($(echo ${{ inputs.examples }} | tr ',' ' '))
|
||||
examples_json=$(printf '%s\n' "${examples[@]}" | sort -u | jq -R '.' | jq -sc '.')
|
||||
echo "examples=$examples_json" >> $GITHUB_OUTPUT
|
||||
nodes=($(echo ${{ inputs.nodes }} | tr ',' ' '))
|
||||
nodes_json=$(printf '%s\n' "${nodes[@]}" | sort -u | jq -R '.' | jq -sc '.')
|
||||
echo "nodes=$nodes_json" >> $GITHUB_OUTPUT
|
||||
|
||||
build-deploy-gmc:
|
||||
needs: [get-test-matrix]
|
||||
if: ${{ fromJSON(inputs.deploy_gmc) }}
|
||||
strategy:
|
||||
matrix:
|
||||
node: ${{ fromJson(needs.get-test-matrix.outputs.nodes) }}
|
||||
fail-fast: false
|
||||
uses: ./.github/workflows/_gmc-workflow.yml
|
||||
with:
|
||||
node: ${{ matrix.node }}
|
||||
tag: ${{ inputs.tag }}
|
||||
opea_branch: ${{ inputs.opea_branch }}
|
||||
secrets: inherit
|
||||
|
||||
run-examples:
|
||||
needs: [get-test-matrix, build-deploy-gmc]
|
||||
if: always()
|
||||
strategy:
|
||||
matrix:
|
||||
example: ${{ fromJson(needs.get-test-matrix.outputs.examples) }}
|
||||
node: ${{ fromJson(needs.get-test-matrix.outputs.nodes) }}
|
||||
fail-fast: false
|
||||
uses: ./.github/workflows/_example-workflow.yml
|
||||
with:
|
||||
node: ${{ matrix.node }}
|
||||
example: ${{ matrix.example }}
|
||||
tag: ${{ inputs.tag }}
|
||||
build: ${{ fromJSON(inputs.build) }}
|
||||
scan: ${{ fromJSON(inputs.scan) }}
|
||||
test_compose: ${{ fromJSON(inputs.test_compose) }}
|
||||
test_k8s: ${{ fromJSON(inputs.test_k8s) }}
|
||||
test_gmc: ${{ fromJSON(inputs.test_gmc) }}
|
||||
opea_branch: ${{ inputs.opea_branch }}
|
||||
secrets: inherit
|
||||
43
.github/workflows/manual-freeze-images.yml
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Freeze base images and 3rd party images on manual event
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
freeze-images:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: install skopeo
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt -y install skopeo
|
||||
|
||||
- name: Set up Git
|
||||
run: |
|
||||
git config --global user.name "NeuralChatBot"
|
||||
git config --global user.email "grp_neural_chat_bot@intel.com"
|
||||
git remote set-url origin https://NeuralChatBot:"${{ secrets.ACTION_TOKEN }}"@github.com/opea-project/GenAIExamples.git
|
||||
|
||||
- name: Run script
|
||||
run: |
|
||||
bash .github/workflows/scripts/freeze_images.sh
|
||||
|
||||
- name: Commit changes
|
||||
run: |
|
||||
git add .
|
||||
git commit -s -m "Freeze third party images tag"
|
||||
git push
|
||||
46
.github/workflows/manual-freeze-tag.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Freeze OPEA images release tag in readme on manual event
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
default: "latest"
|
||||
description: "Tag to apply to images"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
freeze-tag:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.ref }}
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Set up Git
|
||||
run: |
|
||||
git config --global user.name "NeuralChatBot"
|
||||
git config --global user.email "grp_neural_chat_bot@intel.com"
|
||||
git remote set-url origin https://NeuralChatBot:"${{ secrets.ACTION_TOKEN }}"@github.com/opea-project/GenAIExamples.git
|
||||
|
||||
- name: Run script
|
||||
run: |
|
||||
find . -name "*.md" | xargs sed -i "s|^docker\ compose|TAG=${{ github.event.inputs.tag }}\ docker\ compose|g"
|
||||
find . -type f -name "*.yaml" \( -path "*/benchmark/*" -o -path "*/kubernetes/*" \) | xargs sed -i -E 's/(opea\/[A-Za-z0-9\-]*:)latest/\1${{ github.event.inputs.tag }}/g'
|
||||
find . -type f -name "*.md" \( -path "*/benchmark/*" -o -path "*/kubernetes/*" \) | xargs sed -i -E 's/(opea\/[A-Za-z0-9\-]*:)latest/\1${{ github.event.inputs.tag }}/g'
|
||||
|
||||
- name: Commit changes
|
||||
run: |
|
||||
git add .
|
||||
git commit -s -m "Freeze OPEA images tag"
|
||||
git push
|
||||
78
.github/workflows/manual-image-build.yml
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Build latest images on manual event
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
registry:
|
||||
default: ""
|
||||
description: "Registry to store images,e.g., docker.io, default is empty"
|
||||
required: false
|
||||
type: string
|
||||
services:
|
||||
default: "AudioQnA,ChatQnA,CodeGen,CodeTrans,DocSum,FaqGen,SearchQnA,Translation"
|
||||
description: "List of examples to build"
|
||||
required: true
|
||||
type: string
|
||||
tag:
|
||||
default: "latest"
|
||||
description: "Tag to apply to images"
|
||||
required: true
|
||||
type: string
|
||||
nodes:
|
||||
default: "docker-build-xeon,docker-build-gaudi"
|
||||
description: "List of node to run the build on"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
jobs:
|
||||
get-build-matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
services: ${{ steps.get-services.outputs.services }}
|
||||
nodes: ${{ steps.get-services.outputs.nodes }}
|
||||
steps:
|
||||
- name: Get test Services
|
||||
id: get-services
|
||||
run: |
|
||||
set -x
|
||||
service_list=($(echo ${{ github.event.inputs.services }} | tr ',' ' '))
|
||||
services=$(printf '%s\n' "${service_list[@]}" | sort -u | jq -R '.' | jq -sc '.')
|
||||
echo "services=$services" >> $GITHUB_OUTPUT
|
||||
node_list=($(echo ${{ github.event.inputs.nodes }} | tr ',' ' '))
|
||||
nodes=$(printf '%s\n' "${node_list[@]}" | sort -u | jq -R '.' | jq -sc '.')
|
||||
echo "nodes=$nodes" >> $GITHUB_OUTPUT
|
||||
|
||||
image-build:
|
||||
needs: get-build-matrix
|
||||
strategy:
|
||||
matrix:
|
||||
service: ${{ fromJSON(needs.get-build-matrix.outputs.services) }}
|
||||
node: ${{ fromJSON(needs.get-build-matrix.outputs.nodes) }}
|
||||
runs-on: ${{ matrix.node }}
|
||||
continue-on-error: true
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: |
|
||||
sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Config image repo
|
||||
run: |
|
||||
if [[ -z "${{ github.event.inputs.registry }}" ]]; then
|
||||
echo "image_repo=${OPEA_IMAGE_REPO}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "image_repo=${{ github.event.inputs.registry }}/" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build image
|
||||
uses: opea-project/validation/actions/image-build@main
|
||||
with:
|
||||
work_dir: ${{ github.workspace }}/${{ matrix.service }}
|
||||
docker_compose_path: ${{ github.workspace }}/.github/workflows/docker/compose/${{ matrix.service }}-compose.yaml
|
||||
registry: ${{ env.image_repo }}opea
|
||||
tag: ${{ github.event.inputs.tag }}
|
||||
50
.github/workflows/pr-bum_list_check.yml
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Check Requirements
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
check-requirements:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout PR branch
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Save PR requirements
|
||||
run: |
|
||||
find . -name "requirements.txt" -exec cat {} \; | \
|
||||
grep -v '^\s*#' | \
|
||||
grep -v '^\s*$' | \
|
||||
grep -v '^\s*-' | \
|
||||
sed 's/^\s*//' | \
|
||||
awk -F'[>=<]' '{print $1}' | \
|
||||
sort -u > pr-requirements.txt
|
||||
cat pr-requirements.txt
|
||||
|
||||
- name: Checkout main branch
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
ref: main
|
||||
path: main-branch
|
||||
|
||||
- name: Save main branch requirements
|
||||
run: |
|
||||
find ./main-branch -name "requirements.txt" -exec cat {} \; | \
|
||||
grep -v '^\s*#' | \
|
||||
grep -v '^\s*$' | \
|
||||
grep -v '^\s*-' | \
|
||||
sed 's/^\s*//' | \
|
||||
awk -F'[>=<]' '{print $1}' | \
|
||||
sort -u > main-requirements.txt
|
||||
cat main-requirements.txt
|
||||
|
||||
- name: Compare requirements
|
||||
run: |
|
||||
comm -23 pr-requirements.txt main-requirements.txt > added-packages.txt
|
||||
if [ -s added-packages.txt ]; then
|
||||
echo "New packages found in PR:" && cat added-packages.txt
|
||||
else
|
||||
echo "No new packages found😊."
|
||||
fi
|
||||
40
.github/workflows/pr-docker-compose-e2e.yml
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: E2E test with docker compose
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- "**/docker/**"
|
||||
- "**/tests/**"
|
||||
- "**/ui/**"
|
||||
- "!**.md"
|
||||
- "!**.txt"
|
||||
- .github/workflows/pr-docker-compose-e2e.yml
|
||||
|
||||
# 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:
|
||||
get-test-matrix:
|
||||
uses: ./.github/workflows/_get-test-matrix.yml
|
||||
with:
|
||||
diff_excluded_files: '.github|README.md|*.txt|deprecate|kubernetes|manifest|gmc|assets'
|
||||
|
||||
example-test:
|
||||
needs: [get-test-matrix]
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.get-test-matrix.outputs.run_matrix) }}
|
||||
fail-fast: false
|
||||
uses: ./.github/workflows/_run-docker-compose.yml
|
||||
with:
|
||||
registry: "opea"
|
||||
tag: "ci"
|
||||
example: ${{ matrix.example }}
|
||||
hardware: ${{ matrix.hardware }}
|
||||
secrets: inherit
|
||||
38
.github/workflows/pr-gmc-e2e.yaml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: E2E test with GMC
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- "**/kubernetes/**"
|
||||
- "**/tests/test_gmc**"
|
||||
- "!**.md"
|
||||
- "!**.txt"
|
||||
- "!**/kubernetes/manifests/**"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
job1:
|
||||
uses: ./.github/workflows/_get-test-matrix.yml
|
||||
with:
|
||||
diff_excluded_files: '.github|deprecated|docker|assets|*.md|*.txt'
|
||||
xeon_server_label: 'xeon'
|
||||
gaudi_server_label: 'gaudi'
|
||||
|
||||
gmc-test:
|
||||
needs: [job1]
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.job1.outputs.run_matrix) }}
|
||||
uses: ./.github/workflows/_gmc-e2e.yml
|
||||
with:
|
||||
example: ${{ matrix.example }}
|
||||
hardware: ${{ matrix.hardware }}
|
||||
secrets: inherit
|
||||
48
.github/workflows/pr-manifest-e2e.yml
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: E2E test with manifests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- "**/kubernetes/manifests/**"
|
||||
- "**/tests/test_manifest**"
|
||||
- "!**.md"
|
||||
- "!**.txt"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
job1:
|
||||
uses: ./.github/workflows/_get-test-matrix.yml
|
||||
with:
|
||||
diff_excluded_files: '.github|deprecated|docker|assets|*.md|*.txt'
|
||||
xeon_server_label: 'xeon'
|
||||
gaudi_server_label: 'gaudi'
|
||||
|
||||
mega-image-build:
|
||||
needs: job1
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.job1.outputs.run_matrix) }}
|
||||
uses: ./.github/workflows/_image-build.yml
|
||||
with:
|
||||
image_tag: ${{ github.event.pull_request.head.sha }}
|
||||
mega_service: "${{ matrix.example }}"
|
||||
runner_label: "docker-build-${{ matrix.hardware }}"
|
||||
|
||||
manifest-test:
|
||||
needs: [job1, mega-image-build]
|
||||
strategy:
|
||||
matrix: ${{ fromJSON(needs.job1.outputs.run_matrix) }}
|
||||
uses: ./.github/workflows/_manifest-e2e.yml
|
||||
with:
|
||||
example: ${{ matrix.example }}
|
||||
hardware: ${{ matrix.hardware }}
|
||||
tag: ${{ needs.mega-image-build.outputs.image_tag }}
|
||||
secrets: inherit
|
||||
@@ -9,7 +9,7 @@ on:
|
||||
types: [opened, reopened, ready_for_review, synchronize] # added `ready_for_review` since draft is skipped
|
||||
paths:
|
||||
- "**/kubernetes/manifests/**"
|
||||
- .github/workflows/manifest-validate.yaml
|
||||
- .github/workflows/manifest-validate.yml
|
||||
workflow_dispatch:
|
||||
|
||||
# If there is a new commit, the previous jobs will be canceled
|
||||
44
.github/workflows/pr-path_detection.yml
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Check for missing Dockerfile paths in repo comps
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize]
|
||||
|
||||
jobs:
|
||||
check-dockerfile-paths:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout repo GenAIExamples
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Clone repo GenAIComps
|
||||
run: |
|
||||
cd ..
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
|
||||
- name: Check for missing Dockerfile paths in GenAIComps
|
||||
run: |
|
||||
cd ${{github.workspace}}
|
||||
miss="FALSE"
|
||||
while IFS=: read -r file line content; do
|
||||
dockerfile_path=$(echo "$content" | awk -F '-f ' '{print $2}' | awk '{print $1}')
|
||||
if [[ ! -f "../GenAIComps/${dockerfile_path}" ]]; then
|
||||
miss="TRUE"
|
||||
echo "Missing Dockerfile: GenAIComps/${dockerfile_path} (Referenced in GenAIExamples/${file}:${line})"
|
||||
fi
|
||||
done < <(grep -Ern 'docker build .* -f comps/.+/Dockerfile' --include='*.md' .)
|
||||
|
||||
|
||||
if [[ "$miss" == "TRUE" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
shell: bash
|
||||
57
.github/workflows/push-image-build.yml
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# Test
|
||||
name: Build latest images on push event
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'main' ]
|
||||
paths:
|
||||
- "**/docker/*.py"
|
||||
- "**/docker/Dockerfile"
|
||||
- "**/docker/ui/**"
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-on-push
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
job1:
|
||||
uses: ./.github/workflows/_get-test-matrix.yml
|
||||
|
||||
mega-image-build:
|
||||
needs: job1
|
||||
strategy:
|
||||
matrix:
|
||||
workload: ${{ fromJSON(needs.job1.outputs.run_matrix).include.*.example }}
|
||||
hardware: ["gaudi","xeon"]
|
||||
runs-on: docker-build-${{ matrix.hardware }}
|
||||
steps:
|
||||
- name: Clean up Working Directory
|
||||
run: |
|
||||
sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check Docker Compose File Exists
|
||||
env:
|
||||
service: ${{ matrix.workload }}
|
||||
run: |
|
||||
docker_compose_path="${{ github.workspace }}/.github/workflows/docker/compose/${service}-compose.yaml"
|
||||
if [ -e $docker_compose_path ]; then
|
||||
echo "file_exists=true" >> $GITHUB_ENV
|
||||
echo "docker_compose_path=${docker_compose_path}" >> $GITHUB_ENV
|
||||
else
|
||||
echo "file_exists=false" >> $GITHUB_ENV
|
||||
echo "docker_compose_path=${docker_compose_path} for this service does not exist, so skipping image build for this service!!!"
|
||||
fi
|
||||
|
||||
- name: Build Image
|
||||
if: env.file_exists == 'true'
|
||||
uses: opea-project/validation/actions/image-build@main
|
||||
with:
|
||||
work_dir: ${{ github.workspace }}/${{ matrix.workload }}
|
||||
docker_compose_path: ${{ env.docker_compose_path }}
|
||||
registry: ${OPEA_IMAGE_REPO}opea
|
||||
49
.github/workflows/push-images-path-detection.yml
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
name: Check the validity of links in docker_images_list.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
types: [opened, reopened, ready_for_review, synchronize]
|
||||
|
||||
jobs:
|
||||
check-dockerfile-paths:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Clean Up Working Directory
|
||||
run: sudo rm -rf ${{github.workspace}}/*
|
||||
|
||||
- name: Checkout repo GenAIExamples
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Check the validity of links
|
||||
run: |
|
||||
cd ${{github.workspace}}
|
||||
miss="FALSE"
|
||||
while IFS=: read -r line link; do
|
||||
http_status=$(curl -o /dev/null -s -w "%{http_code}" "$link")
|
||||
if [ "$http_status" -eq 200 ]; then
|
||||
echo "Valid link: $link (Line $line)"
|
||||
else
|
||||
echo "Broken link: $link (Line $line) (Status $http_status) "
|
||||
echo "-----------------retry strat----------------------"
|
||||
retry_http_status=$(curl -o /dev/null -s -w "%{http_code}" "$link")
|
||||
if [ "$retry_http_status" -eq 200 ]; then
|
||||
miss="FALSE"
|
||||
echo "Valid link: $link (Line $line)"
|
||||
echo "---------------Retry is valid---------------------"
|
||||
else
|
||||
miss="TRUE"
|
||||
echo "Retry broken link: $link (Line $line) (Status $http_status) "
|
||||
echo "-------------Retry is not valid-------------------"
|
||||
fi
|
||||
fi
|
||||
done < <(grep -n -oP '(?<=a href=")[^"]*(?=">)' ../../docker_images_list.md)
|
||||
|
||||
if [[ "$miss" == "TRUE" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
shell: bash
|
||||
59
.github/workflows/push-infra-issue-creation.yml
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'main','issue' ]
|
||||
paths:
|
||||
- "**/docker/*/compose.yaml"
|
||||
|
||||
name: Create an issue to GenAIInfra on push
|
||||
jobs:
|
||||
job1:
|
||||
name: Create issue
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout out Repo
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Get changed files
|
||||
id: get-changed-files
|
||||
run: |
|
||||
set -xe
|
||||
base_commit=$(git rev-parse HEAD~1)
|
||||
merged_commit=$(git log -1 --format='%H')
|
||||
changed_files="$(git diff --name-only ${base_commit} ${merged_commit} | \
|
||||
grep -E '.*/docker/.*/compose.yaml')" || true
|
||||
|
||||
examples=$(printf '%s\n' "${changed_files[@]}" | grep '/' | cut -d'/' -f1 | sort -u)
|
||||
format_examples=$(echo "$examples" | tr '\n' ',')
|
||||
format_examples=${format_examples%,}
|
||||
echo "examples=$format_examples" >> $GITHUB_ENV
|
||||
|
||||
format_changed_files=$(echo "$changed_files" | awk '{print "- "$0}')
|
||||
echo "changed_files<<EOF" >> $GITHUB_ENV
|
||||
echo "$format_changed_files" >> $GITHUB_ENV
|
||||
echo "EOF" >> $GITHUB_ENV
|
||||
|
||||
- name: Create Issue
|
||||
uses: daisy-ycguo/create-issue-action@stable
|
||||
with:
|
||||
token: ${{ secrets.Infra_Issue_Token }}
|
||||
owner: opea-project
|
||||
repo: GenAIInfra
|
||||
title: |
|
||||
[ci-auto] GenAIExample ${{ env.examples }} compose.yaml got changed.
|
||||
assignees: lianhao
|
||||
labels: helm
|
||||
body: |
|
||||
## GenAIExample ${{ env.examples }} compose.yaml got changed
|
||||
|
||||
Below files are changed in [this commit](https://github.com/opea-project/GenAIExamples/commit/${{ github.sha }})
|
||||
|
||||
${{ env.changed_files }}
|
||||
|
||||
Please verify if the helm charts and manifests need to be changed accordingly.
|
||||
|
||||
> This issue was created automatically by CI.
|
||||
72
.github/workflows/scripts/build_push.sh
vendored
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -xe
|
||||
|
||||
IMAGE_REPO=${IMAGE_REPO:-$OPEA_IMAGE_REPO}
|
||||
IMAGE_TAG=${IMAGE_TAG:-latest}
|
||||
|
||||
function getImagenameFromMega() {
|
||||
echo $(echo "$1" | tr '[:upper:]' '[:lower:]')
|
||||
}
|
||||
|
||||
function checkExist() {
|
||||
IMAGE_NAME=$1
|
||||
if [ $(curl -X GET http://localhost:5000/v2/opea/${IMAGE_NAME}/tags/list | grep -c ${IMAGE_TAG}) -ne 0 ]; then
|
||||
echo "true"
|
||||
else
|
||||
echo "false"
|
||||
fi
|
||||
}
|
||||
|
||||
function docker_build() {
|
||||
# check if if IMAGE_TAG is not "latest" and the image exists in the registry
|
||||
if [ "$IMAGE_TAG" != "latest" ] && [ "$(checkExist $1)" == "true" ]; then
|
||||
echo "Image ${IMAGE_REPO}opea/$1:$IMAGE_TAG already exists in the registry"
|
||||
return
|
||||
fi
|
||||
# docker_build <service_name> <dockerfile>
|
||||
if [ -z "$2" ]; then
|
||||
DOCKERFILE_PATH=Dockerfile
|
||||
else
|
||||
DOCKERFILE_PATH=$2
|
||||
fi
|
||||
echo "Building ${IMAGE_REPO}opea/$1:$IMAGE_TAG using Dockerfile $DOCKERFILE_PATH"
|
||||
# if https_proxy and http_proxy are set, pass them to docker build
|
||||
if [ -z "$https_proxy" ]; then
|
||||
docker build --no-cache -t ${IMAGE_REPO}opea/$1:$IMAGE_TAG -f $DOCKERFILE_PATH .
|
||||
else
|
||||
docker build --no-cache -t ${IMAGE_REPO}opea/$1:$IMAGE_TAG --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f $DOCKERFILE_PATH .
|
||||
fi
|
||||
docker push ${IMAGE_REPO}opea/$1:$IMAGE_TAG
|
||||
docker rmi ${IMAGE_REPO}opea/$1:$IMAGE_TAG
|
||||
}
|
||||
|
||||
# $1 is like "apple orange pear"
|
||||
for MEGA_SVC in $1; do
|
||||
case $MEGA_SVC in
|
||||
"ChatQnA"|"CodeGen"|"CodeTrans"|"DocSum"|"Translation"|"AudioQnA"|"SearchQnA"|"FaqGen")
|
||||
cd $MEGA_SVC/docker
|
||||
IMAGE_NAME="$(getImagenameFromMega $MEGA_SVC)"
|
||||
docker_build ${IMAGE_NAME}
|
||||
cd ui
|
||||
docker_build ${IMAGE_NAME}-ui docker/Dockerfile
|
||||
if [ "$MEGA_SVC" == "ChatQnA" ];then
|
||||
docker_build ${IMAGE_NAME}-conversation-ui docker/Dockerfile.react
|
||||
fi
|
||||
if [ "$MEGA_SVC" == "DocSum" ];then
|
||||
docker_build ${IMAGE_NAME}-react-ui docker/Dockerfile.react
|
||||
fi
|
||||
if [ "$MEGA_SVC" == "CodeGen" ];then
|
||||
docker_build ${IMAGE_NAME}-react-ui docker/Dockerfile.react
|
||||
fi
|
||||
;;
|
||||
"VisualQnA")
|
||||
echo "Not supported yet"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown function: $MEGA_SVC"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
@@ -6,12 +6,16 @@
|
||||
source /GenAIExamples/.github/workflows/scripts/change_color
|
||||
log_dir=/GenAIExamples/.github/workflows/scripts/codeScan
|
||||
|
||||
find . -type f \( -name "Dockerfile*" \) -print -exec hadolint --ignore DL3006 --ignore DL3007 --ignore DL3008 {} \; 2>&1 | tee ${log_dir}/hadolint.log
|
||||
find . -type f \( -name "Dockerfile*" \) -print -exec hadolint --ignore DL3006 --ignore DL3007 --ignore DL3008 --ignore DL3013 {} \; 2>&1 | tee ${log_dir}/hadolint.log
|
||||
|
||||
if [[ $(grep -c "error" ${log_dir}/hadolint.log) != 0 ]]; then
|
||||
$BOLD_RED && echo "Error!! Please Click on the artifact button to download and check error details." && $RESET
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ $(grep -c "warning" ${log_dir}/hadolint.log) != 0 ]]; then
|
||||
$BOLD_RED && echo "Warning!! Please Click on the artifact button to download and check warning details." && $RESET
|
||||
exit 1
|
||||
fi
|
||||
$BOLD_PURPLE && echo "Congratulations, Hadolint check passed!" && $LIGHT_PURPLE && echo " You can click on the artifact button to see the log details." && $RESET
|
||||
exit 0
|
||||
|
||||
50
.github/workflows/scripts/freeze_images.sh
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
declare -A dict
|
||||
dict["langchain/langchain"]="docker://docker.io/langchain/langchain"
|
||||
dict["ghcr.io/huggingface/text-generation-inference"]="docker://ghcr.io/huggingface/text-generation-inference"
|
||||
|
||||
function get_latest_version() {
|
||||
repo_image=$1
|
||||
versions=$(skopeo list-tags ${dict[$repo_image]} | jq -r '.Tags[]')
|
||||
printf "version list:\n$versions\n"
|
||||
latest_version=$(printf "%s\n" "${versions[@]}" | grep -E '^[\.0-9\-]+$' | sort -V | tail -n 1)
|
||||
echo "latest version: $latest_version"
|
||||
replace_image_version $repo_image $latest_version
|
||||
}
|
||||
|
||||
function replace_image_version() {
|
||||
repo_image=$1
|
||||
version=$2
|
||||
if [[ -z "$version" ]]; then
|
||||
echo "version is empty"
|
||||
else
|
||||
echo "replace $repo_image:latest with $repo_image:$version"
|
||||
find . -name "Dockerfile" | xargs sed -i "s|$repo_image:latest.*|$repo_image:$version|g"
|
||||
find . -name "*.yaml" | xargs sed -i "s|$repo_image:latest[A-Za-z0-9\-]*|$repo_image:$version|g"
|
||||
find . -name "*.md" | xargs sed -i "s|$repo_image:latest[A-Za-z0-9\-]*|$repo_image:$version|g"
|
||||
fi
|
||||
}
|
||||
|
||||
function check_branch_name() {
|
||||
if [[ "$GITHUB_REF_NAME" == "main" ]]; then
|
||||
echo "$GITHUB_REF_NAME is protected branch"
|
||||
exit 0
|
||||
else
|
||||
echo "branch name is $GITHUB_REF_NAME"
|
||||
fi
|
||||
}
|
||||
|
||||
function main() {
|
||||
check_branch_name
|
||||
for repo_image in "${!dict[@]}"; do
|
||||
echo "::group::check $repo_image"
|
||||
get_latest_version $repo_image
|
||||
echo "::endgroup::"
|
||||
done
|
||||
}
|
||||
|
||||
main
|
||||
@@ -7,7 +7,7 @@ ci:
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
rev: v4.6.0
|
||||
hooks:
|
||||
- id: end-of-file-fixer
|
||||
files: (.*\.(py|md|rst|yaml|yml|json|ts|js|html|svelte|sh))$
|
||||
@@ -24,6 +24,8 @@ repos:
|
||||
- id: requirements-txt-fixer
|
||||
- id: trailing-whitespace
|
||||
files: (.*\.(py|rst|cmake|yaml|yml|json|ts|js|html|svelte|sh))$
|
||||
- id: mixed-line-ending
|
||||
args: [--fix=lf]
|
||||
|
||||
- repo: https://github.com/Lucas-C/pre-commit-hooks
|
||||
rev: v1.5.5
|
||||
@@ -100,21 +102,21 @@ repos:
|
||||
- prettier@3.2.5
|
||||
|
||||
- repo: https://github.com/psf/black.git
|
||||
rev: 24.3.0
|
||||
rev: 24.4.2
|
||||
hooks:
|
||||
- id: black
|
||||
files: (.*\.py)$
|
||||
|
||||
- repo: https://github.com/asottile/blacken-docs
|
||||
rev: 1.16.0
|
||||
rev: 1.18.0
|
||||
hooks:
|
||||
- id: blacken-docs
|
||||
args: [--line-length=120, --skip-errors]
|
||||
additional_dependencies:
|
||||
- black==24.3.0
|
||||
- black==24.4.2
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.6
|
||||
rev: v2.3.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
args: [-w]
|
||||
@@ -122,7 +124,7 @@ repos:
|
||||
- tomli
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.3.5
|
||||
rev: v0.5.0
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix, --exit-non-zero-on-fix, --no-cache]
|
||||
|
||||
106
AgentQnA/README.md
Normal file
@@ -0,0 +1,106 @@
|
||||
# Agents for Question Answering
|
||||
|
||||
## Overview
|
||||
|
||||
This example showcases a hierarchical multi-agent system for question-answering applications. The architecture diagram is shown below. The supervisor agent interfaces with the user and dispatch tasks to the worker agent and other tools to gather information and come up with answers. The worker agent uses the retrieval tool to generate answers to the queries posted by the supervisor agent. Other tools used by the supervisor agent may include APIs to interface knowledge graphs, SQL databases, external knowledge bases, etc.
|
||||

|
||||
|
||||
### Why Agent for question answering?
|
||||
|
||||
1. Improve relevancy of retrieved context.
|
||||
Agent can rephrase user queries, decompose user queries, and iterate to get the most relevant context for answering user's questions. Compared to conventional RAG, RAG agent can significantly improve the correctness and relevancy of the answer.
|
||||
2. Use tools to get additional knowledge.
|
||||
For example, knowledge graphs and SQL databases can be exposed as APIs for Agents to gather knowledge that may be missing in the retrieval vector database.
|
||||
3. Hierarchical agent can further improve performance.
|
||||
Expert worker agents, such as retrieval agent, knowledge graph agent, SQL agent, etc., can provide high-quality output for different aspects of a complex query, and the supervisor agent can aggregate the information together to provide a comprehensive answer.
|
||||
|
||||
### Roadmap
|
||||
|
||||
- v0.9: Worker agent uses open-source websearch tool (duckduckgo), agents use OpenAI GPT-4o-mini as llm backend.
|
||||
- v1.0: Worker agent uses OPEA retrieval megaservice as tool.
|
||||
- v1.0 or later: agents use open-source llm backend.
|
||||
- v1.1 or later: add safeguards
|
||||
|
||||
## Getting started
|
||||
|
||||
1. Build agent docker image </br>
|
||||
First, clone the opea GenAIComps repo
|
||||
|
||||
```
|
||||
export WORKDIR=<your-work-directory>
|
||||
cd $WORKDIR
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
```
|
||||
|
||||
Then build the agent docker image. Both the supervisor agent and the worker agent will use the same docker image, but when we launch the two agents we will specify different strategies and register different tools.
|
||||
|
||||
```
|
||||
cd GenAIComps
|
||||
docker build -t opea/comps-agent-langchain:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/agent/langchain/docker/Dockerfile .
|
||||
```
|
||||
|
||||
2. Launch tool services </br>
|
||||
In this example, we will use some of the mock APIs provided in the Meta CRAG KDD Challenge to demonstrate the benefits of gaining additional context from mock knowledge graphs.
|
||||
|
||||
```
|
||||
docker run -d -p=8080:8000 docker.io/aicrowd/kdd-cup-24-crag-mock-api:v0
|
||||
```
|
||||
|
||||
3. Set up environment for this example </br>
|
||||
First, clone this repo
|
||||
|
||||
```
|
||||
cd $WORKDIR
|
||||
git clone https://github.com/opea-project/GenAIExamples.git
|
||||
```
|
||||
|
||||
Second, set up env vars
|
||||
|
||||
```
|
||||
export TOOLSET_PATH=$WORKDIR/GenAIExamples/AgentQnA/tools/
|
||||
# optional: OPANAI_API_KEY
|
||||
export OPENAI_API_KEY=<your-openai-key>
|
||||
```
|
||||
|
||||
4. Launch agent services</br>
|
||||
The configurations of the supervisor agent and the worker agent are defined in the docker-compose yaml file. We currently use openAI GPT-4o-mini as LLM, and we plan to add support for llama3.1-70B-instruct (served by TGI-Gaudi) in a subsequent release.
|
||||
To use openai llm, run command below.
|
||||
|
||||
```
|
||||
cd docker/openai/
|
||||
bash launch_agent_service_openai.sh
|
||||
```
|
||||
|
||||
## Validate services
|
||||
|
||||
First look at logs of the agent docker containers:
|
||||
|
||||
```
|
||||
docker logs docgrader-agent-endpoint
|
||||
```
|
||||
|
||||
```
|
||||
docker logs react-agent-endpoint
|
||||
```
|
||||
|
||||
You should see something like "HTTP server setup successful" if the docker containers are started successfully.</p>
|
||||
|
||||
Second, validate worker agent:
|
||||
|
||||
```
|
||||
curl http://${ip_address}:9095/v1/chat/completions -X POST -H "Content-Type: application/json" -d '{
|
||||
"query": "Most recent album by Taylor Swift"
|
||||
}'
|
||||
```
|
||||
|
||||
Third, validate supervisor agent:
|
||||
|
||||
```
|
||||
curl http://${ip_address}:9090/v1/chat/completions -X POST -H "Content-Type: application/json" -d '{
|
||||
"query": "Most recent album by Taylor Swift"
|
||||
}'
|
||||
```
|
||||
|
||||
## How to register your own tools with agent
|
||||
|
||||
You can take a look at the tools yaml and python files in this example. For more details, please refer to the "Provide your own tools" section in the instructions [here](https://github.com/minmin-intel/GenAIComps/tree/agent-comp-dev/comps/agent/langchain#-4-provide-your-own-tools).
|
||||
BIN
AgentQnA/assets/agent_qna_arch.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
63
AgentQnA/docker/openai/docker-compose-agent-openai.yaml
Normal file
@@ -0,0 +1,63 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
services:
|
||||
worker-docgrader-agent:
|
||||
image: opea/comps-agent-langchain:latest
|
||||
container_name: docgrader-agent-endpoint
|
||||
volumes:
|
||||
- ${WORKDIR}/GenAIComps/comps/agent/langchain/:/home/user/comps/agent/langchain/
|
||||
- ${TOOLSET_PATH}:/home/user/tools/
|
||||
ports:
|
||||
- "9095:9095"
|
||||
ipc: host
|
||||
environment:
|
||||
ip_address: ${ip_address}
|
||||
strategy: rag_agent
|
||||
recursion_limit: ${recursion_limit}
|
||||
llm_engine: openai
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
model: ${model}
|
||||
temperature: ${temperature}
|
||||
max_new_tokens: ${max_new_tokens}
|
||||
streaming: false
|
||||
tools: /home/user/tools/worker_agent_tools.yaml
|
||||
require_human_feedback: false
|
||||
no_proxy: ${no_proxy}
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
LANGCHAIN_API_KEY: ${LANGCHAIN_API_KEY}
|
||||
LANGCHAIN_TRACING_V2: ${LANGCHAIN_TRACING_V2}
|
||||
LANGCHAIN_PROJECT: "opea-worker-agent-service"
|
||||
port: 9095
|
||||
|
||||
supervisor-react-agent:
|
||||
image: opea/comps-agent-langchain:latest
|
||||
container_name: react-agent-endpoint
|
||||
volumes:
|
||||
- ${WORKDIR}/GenAIComps/comps/agent/langchain/:/home/user/comps/agent/langchain/
|
||||
- ${TOOLSET_PATH}:/home/user/tools/
|
||||
ports:
|
||||
- "9090:9090"
|
||||
ipc: host
|
||||
environment:
|
||||
ip_address: ${ip_address}
|
||||
strategy: react_langgraph
|
||||
recursion_limit: ${recursion_limit}
|
||||
llm_engine: openai
|
||||
OPENAI_API_KEY: ${OPENAI_API_KEY}
|
||||
model: ${model}
|
||||
temperature: ${temperature}
|
||||
max_new_tokens: ${max_new_tokens}
|
||||
streaming: ${streaming}
|
||||
tools: /home/user/tools/supervisor_agent_tools.yaml
|
||||
require_human_feedback: false
|
||||
no_proxy: ${no_proxy}
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
LANGCHAIN_API_KEY: ${LANGCHAIN_API_KEY}
|
||||
LANGCHAIN_TRACING_V2: ${LANGCHAIN_TRACING_V2}
|
||||
LANGCHAIN_PROJECT: "opea-supervisor-agent-service"
|
||||
CRAG_SERVER: $CRAG_SERVER
|
||||
WORKER_AGENT_URL: $WORKER_AGENT_URL
|
||||
port: 9090
|
||||
13
AgentQnA/docker/openai/launch_agent_service_openai.sh
Normal file
@@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
export ip_address=$(hostname -I | awk '{print $1}')
|
||||
export recursion_limit=12
|
||||
export model="gpt-4o-mini-2024-07-18"
|
||||
export temperature=0
|
||||
export max_new_tokens=512
|
||||
export OPENAI_API_KEY=${OPENAI_API_KEY}
|
||||
export WORKER_AGENT_URL="http://${ip_address}:9095/v1/chat/completions"
|
||||
export CRAG_SERVER=http://${ip_address}:8080
|
||||
|
||||
docker compose -f docker-compose-agent-openai.yaml up -d
|
||||
75
AgentQnA/tests/_test_agentqna_on_xeon.sh
Normal file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
set -e
|
||||
echo "IMAGE_REPO=${IMAGE_REPO}"
|
||||
echo "OPENAI_API_KEY=${OPENAI_API_KEY}"
|
||||
|
||||
WORKPATH=$(dirname "$PWD")
|
||||
export WORKDIR=$WORKPATH/../../
|
||||
echo "WORKDIR=${WORKDIR}"
|
||||
export ip_address=$(hostname -I | awk '{print $1}')
|
||||
export TOOLSET_PATH=$WORKDIR/GenAIExamples/AgentQnA/tools/
|
||||
|
||||
function build_agent_docker_image() {
|
||||
cd $WORKDIR
|
||||
if [ ! -d "GenAIComps" ] ; then
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
fi
|
||||
cd GenAIComps
|
||||
echo PWD: $(pwd)
|
||||
docker build -t opea/comps-agent-langchain:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/agent/langchain/docker/Dockerfile .
|
||||
}
|
||||
|
||||
function start_services() {
|
||||
echo "Starting CRAG server"
|
||||
docker run -d -p=8080:8000 docker.io/aicrowd/kdd-cup-24-crag-mock-api:v0
|
||||
echo "Starting Agent services"
|
||||
cd $WORKDIR/GenAIExamples/AgentQnA/docker/openai
|
||||
bash launch_agent_service_openai.sh
|
||||
}
|
||||
|
||||
function validate() {
|
||||
local CONTENT="$1"
|
||||
local EXPECTED_RESULT="$2"
|
||||
local SERVICE_NAME="$3"
|
||||
|
||||
if echo "$CONTENT" | grep -q "$EXPECTED_RESULT"; then
|
||||
echo "[ $SERVICE_NAME ] Content is as expected: $CONTENT"
|
||||
echo 0
|
||||
else
|
||||
echo "[ $SERVICE_NAME ] Content does not match the expected result: $CONTENT"
|
||||
echo 1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
function run_tests() {
|
||||
echo "----------------Test supervisor agent ----------------"
|
||||
local CONTENT=$(http_proxy="" curl http://${ip_address}:9090/v1/chat/completions -X POST -H "Content-Type: application/json" -d '{
|
||||
"query": "Most recent album by Taylor Swift"
|
||||
}')
|
||||
local EXIT_CODE=$(validate "$CONTENT" "Taylor" "react-agent-endpoint")
|
||||
docker logs react-agent-endpoint
|
||||
if [ "$EXIT_CODE" == "1" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
function stop_services() {
|
||||
echo "Stopping CRAG server"
|
||||
docker stop $(docker ps -q --filter ancestor=docker.io/aicrowd/kdd-cup-24-crag-mock-api:v0)
|
||||
echo "Stopping Agent services"
|
||||
docker stop $(docker ps -q --filter ancestor=opea/comps-agent-langchain:latest)
|
||||
}
|
||||
|
||||
function main() {
|
||||
build_agent_docker_image
|
||||
start_services
|
||||
run_tests
|
||||
stop_services
|
||||
}
|
||||
|
||||
main
|
||||
330
AgentQnA/tools/pycragapi.py
Normal file
@@ -0,0 +1,330 @@
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
# All rights reserved.
|
||||
|
||||
# This source code is licensed under the license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
import json
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
import requests
|
||||
|
||||
|
||||
class CRAG(object):
|
||||
"""A client for interacting with the CRAG server, offering methods to query various domains such as Open, Movie, Finance, Music, and Sports. Each method corresponds to an API endpoint on the CRAG server.
|
||||
|
||||
Attributes:
|
||||
server (str): The base URL of the CRAG server. Defaults to "http://127.0.0.1:8080".
|
||||
|
||||
Methods:
|
||||
open_search_entity_by_name(query: str) -> dict: Search for entities by name in the Open domain.
|
||||
open_get_entity(entity: str) -> dict: Retrieve detailed information about an entity in the Open domain.
|
||||
movie_get_person_info(person_name: str) -> dict: Get information about a person related to movies.
|
||||
movie_get_movie_info(movie_name: str) -> dict: Get information about a movie.
|
||||
movie_get_year_info(year: str) -> dict: Get information about movies released in a specific year.
|
||||
movie_get_movie_info_by_id(movie_id: int) -> dict: Get movie information by its unique ID.
|
||||
movie_get_person_info_by_id(person_id: int) -> dict: Get person information by their unique ID.
|
||||
finance_get_company_name(query: str) -> dict: Search for company names in the finance domain.
|
||||
finance_get_ticker_by_name(query: str) -> dict: Retrieve the ticker symbol for a given company name.
|
||||
finance_get_price_history(ticker_name: str) -> dict: Get the price history for a given ticker symbol.
|
||||
finance_get_detailed_price_history(ticker_name: str) -> dict: Get detailed price history for a ticker symbol.
|
||||
finance_get_dividends_history(ticker_name: str) -> dict: Get dividend history for a ticker symbol.
|
||||
finance_get_market_capitalization(ticker_name: str) -> dict: Retrieve market capitalization for a ticker symbol.
|
||||
finance_get_eps(ticker_name: str) -> dict: Get earnings per share (EPS) for a ticker symbol.
|
||||
finance_get_pe_ratio(ticker_name: str) -> dict: Get the price-to-earnings (PE) ratio for a ticker symbol.
|
||||
finance_get_info(ticker_name: str) -> dict: Get financial information for a ticker symbol.
|
||||
music_search_artist_entity_by_name(artist_name: str) -> dict: Search for music artists by name.
|
||||
music_search_song_entity_by_name(song_name: str) -> dict: Search for songs by name.
|
||||
music_get_billboard_rank_date(rank: int, date: str = None) -> dict: Get Billboard ranking for a specific rank and date.
|
||||
music_get_billboard_attributes(date: str, attribute: str, song_name: str) -> dict: Get attributes of a song from Billboard rankings.
|
||||
music_grammy_get_best_artist_by_year(year: int) -> dict: Get the Grammy Best New Artist for a specific year.
|
||||
music_grammy_get_award_count_by_artist(artist_name: str) -> dict: Get the total Grammy awards won by an artist.
|
||||
music_grammy_get_award_count_by_song(song_name: str) -> dict: Get the total Grammy awards won by a song.
|
||||
music_grammy_get_best_song_by_year(year: int) -> dict: Get the Grammy Song of the Year for a specific year.
|
||||
music_grammy_get_award_date_by_artist(artist_name: str) -> dict: Get the years an artist won a Grammy award.
|
||||
music_grammy_get_best_album_by_year(year: int) -> dict: Get the Grammy Album of the Year for a specific year.
|
||||
music_grammy_get_all_awarded_artists() -> dict: Get all artists awarded the Grammy Best New Artist.
|
||||
music_get_artist_birth_place(artist_name: str) -> dict: Get the birthplace of an artist.
|
||||
music_get_artist_birth_date(artist_name: str) -> dict: Get the birth date of an artist.
|
||||
music_get_members(band_name: str) -> dict: Get the member list of a band.
|
||||
music_get_lifespan(artist_name: str) -> dict: Get the lifespan of an artist.
|
||||
music_get_song_author(song_name: str) -> dict: Get the author of a song.
|
||||
music_get_song_release_country(song_name: str) -> dict: Get the release country of a song.
|
||||
music_get_song_release_date(song_name: str) -> dict: Get the release date of a song.
|
||||
music_get_artist_all_works(artist_name: str) -> dict: Get all works by an artist.
|
||||
sports_soccer_get_games_on_date(team_name: str, date: str) -> dict: Get soccer games on a specific date.
|
||||
sports_nba_get_games_on_date(team_name: str, date: str) -> dict: Get NBA games on a specific date.
|
||||
sports_nba_get_play_by_play_data_by_game_ids(game_ids: List[str]) -> dict: Get NBA play by play data for a set of game ids.
|
||||
|
||||
Note:
|
||||
Each method performs a POST request to the corresponding API endpoint and returns the response as a JSON dictionary.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.server = os.environ.get("CRAG_SERVER", "http://127.0.0.1:8080")
|
||||
|
||||
def open_search_entity_by_name(self, query: str):
|
||||
url = self.server + "/open/search_entity_by_name"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": query}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def open_get_entity(self, entity: str):
|
||||
url = self.server + "/open/get_entity"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": entity}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def movie_get_person_info(self, person_name: str):
|
||||
url = self.server + "/movie/get_person_info"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": person_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def movie_get_movie_info(self, movie_name: str):
|
||||
url = self.server + "/movie/get_movie_info"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": movie_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def movie_get_year_info(self, year: str):
|
||||
url = self.server + "/movie/get_year_info"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": year}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def movie_get_movie_info_by_id(self, movid_id: int):
|
||||
url = self.server + "/movie/get_movie_info_by_id"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": movid_id}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def movie_get_person_info_by_id(self, person_id: int):
|
||||
url = self.server + "/movie/get_person_info_by_id"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": person_id}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_company_name(self, query: str):
|
||||
url = self.server + "/finance/get_company_name"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": query}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_ticker_by_name(self, query: str):
|
||||
url = self.server + "/finance/get_ticker_by_name"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": query}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_price_history(self, ticker_name: str):
|
||||
url = self.server + "/finance/get_price_history"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": ticker_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_detailed_price_history(self, ticker_name: str):
|
||||
url = self.server + "/finance/get_detailed_price_history"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": ticker_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_dividends_history(self, ticker_name: str):
|
||||
url = self.server + "/finance/get_dividends_history"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": ticker_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_market_capitalization(self, ticker_name: str):
|
||||
url = self.server + "/finance/get_market_capitalization"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": ticker_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_eps(self, ticker_name: str):
|
||||
url = self.server + "/finance/get_eps"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": ticker_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_pe_ratio(self, ticker_name: str):
|
||||
url = self.server + "/finance/get_pe_ratio"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": ticker_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def finance_get_info(self, ticker_name: str):
|
||||
url = self.server + "/finance/get_info"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": ticker_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_search_artist_entity_by_name(self, artist_name: str):
|
||||
url = self.server + "/music/search_artist_entity_by_name"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": artist_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_search_song_entity_by_name(self, song_name: str):
|
||||
url = self.server + "/music/search_song_entity_by_name"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": song_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_billboard_rank_date(self, rank: int, date: str = None):
|
||||
url = self.server + "/music/get_billboard_rank_date"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"rank": rank, "date": date}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_billboard_attributes(self, date: str, attribute: str, song_name: str):
|
||||
url = self.server + "/music/get_billboard_attributes"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"date": date, "attribute": attribute, "song_name": song_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_grammy_get_best_artist_by_year(self, year: int):
|
||||
url = self.server + "/music/grammy_get_best_artist_by_year"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": year}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_grammy_get_award_count_by_artist(self, artist_name: str):
|
||||
url = self.server + "/music/grammy_get_award_count_by_artist"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": artist_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_grammy_get_award_count_by_song(self, song_name: str):
|
||||
url = self.server + "/music/grammy_get_award_count_by_song"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": song_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_grammy_get_best_song_by_year(self, year: int):
|
||||
url = self.server + "/music/grammy_get_best_song_by_year"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": year}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_grammy_get_award_date_by_artist(self, artist_name: str):
|
||||
url = self.server + "/music/grammy_get_award_date_by_artist"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": artist_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_grammy_get_best_album_by_year(self, year: int):
|
||||
url = self.server + "/music/grammy_get_best_album_by_year"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": year}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_grammy_get_all_awarded_artists(self):
|
||||
url = self.server + "/music/grammy_get_all_awarded_artists"
|
||||
headers = {"accept": "application/json"}
|
||||
result = requests.post(url, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_artist_birth_place(self, artist_name: str):
|
||||
url = self.server + "/music/get_artist_birth_place"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": artist_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_artist_birth_date(self, artist_name: str):
|
||||
url = self.server + "/music/get_artist_birth_date"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": artist_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_members(self, band_name: str):
|
||||
url = self.server + "/music/get_members"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": band_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_lifespan(self, artist_name: str):
|
||||
url = self.server + "/music/get_lifespan"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": artist_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_song_author(self, song_name: str):
|
||||
url = self.server + "/music/get_song_author"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": song_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_song_release_country(self, song_name: str):
|
||||
url = self.server + "/music/get_song_release_country"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": song_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_song_release_date(self, song_name: str):
|
||||
url = self.server + "/music/get_song_release_date"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": song_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def music_get_artist_all_works(self, song_name: str):
|
||||
url = self.server + "/music/get_artist_all_works"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"query": song_name}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def sports_soccer_get_games_on_date(self, date: str, team_name: str = None):
|
||||
url = self.server + "/sports/soccer/get_games_on_date"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"team_name": team_name, "date": date}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def sports_nba_get_games_on_date(self, date: str, team_name: str = None):
|
||||
url = self.server + "/sports/nba/get_games_on_date"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"team_name": team_name, "date": date}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
|
||||
def sports_nba_get_play_by_play_data_by_game_ids(self, game_ids: List[str]):
|
||||
url = self.server + "/sports/nba/get_play_by_play_data_by_game_ids"
|
||||
headers = {"accept": "application/json"}
|
||||
data = {"game_ids": game_ids}
|
||||
result = requests.post(url, json=data, headers=headers)
|
||||
return json.loads(result.text)
|
||||
59
AgentQnA/tools/supervisor_agent_tools.yaml
Normal file
@@ -0,0 +1,59 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
search_knowledge_base:
|
||||
description: Search knowledge base for a given query. Returns text related to the query.
|
||||
callable_api: tools.py:search_knowledge_base
|
||||
args_schema:
|
||||
query:
|
||||
type: str
|
||||
description: query
|
||||
return_output: retrieved_data
|
||||
|
||||
get_artist_birth_place:
|
||||
description: Get the birth place of an artist.
|
||||
callable_api: tools.py:get_artist_birth_place
|
||||
args_schema:
|
||||
artist_name:
|
||||
type: str
|
||||
description: artist name
|
||||
return_output: birth_place
|
||||
|
||||
get_billboard_rank_date:
|
||||
description: Get Billboard ranking for a specific rank and date.
|
||||
callable_api: tools.py:get_billboard_rank_date
|
||||
args_schema:
|
||||
rank:
|
||||
type: int
|
||||
description: song name
|
||||
date:
|
||||
type: str
|
||||
description: date
|
||||
return_output: billboard_info
|
||||
|
||||
get_song_release_date:
|
||||
description: Get the release date of a song.
|
||||
callable_api: tools.py:get_song_release_date
|
||||
args_schema:
|
||||
song_name:
|
||||
type: str
|
||||
description: song name
|
||||
return_output: release_date
|
||||
|
||||
get_members:
|
||||
description: Get the member list of a band.
|
||||
callable_api: tools.py:get_members
|
||||
args_schema:
|
||||
band_name:
|
||||
type: str
|
||||
description: band name
|
||||
return_output: members
|
||||
|
||||
get_grammy_best_artist_by_year:
|
||||
description: Get the Grammy Best New Artist for a specific year.
|
||||
callable_api: tools.py:get_grammy_best_artist_by_year
|
||||
args_schema:
|
||||
year:
|
||||
type: int
|
||||
description: year
|
||||
return_output: grammy_best_new_artist
|
||||
52
AgentQnA/tools/tools.py
Normal file
@@ -0,0 +1,52 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import os
|
||||
|
||||
import requests
|
||||
from tools.pycragapi import CRAG
|
||||
|
||||
|
||||
def search_knowledge_base(query: str) -> str:
|
||||
"""Search the knowledge base for a specific query."""
|
||||
# use worker agent (DocGrader) to search the knowledge base
|
||||
url = os.environ.get("WORKER_AGENT_URL")
|
||||
print(url)
|
||||
proxies = {"http": ""}
|
||||
payload = {
|
||||
"query": query,
|
||||
}
|
||||
response = requests.post(url, json=payload, proxies=proxies)
|
||||
return response.json()["text"]
|
||||
|
||||
|
||||
def get_grammy_best_artist_by_year(year: int) -> dict:
|
||||
"""Get the Grammy Best New Artist for a specific year."""
|
||||
api = CRAG()
|
||||
year = int(year)
|
||||
return api.music_grammy_get_best_artist_by_year(year)
|
||||
|
||||
|
||||
def get_members(band_name: str) -> dict:
|
||||
"""Get the member list of a band."""
|
||||
api = CRAG()
|
||||
return api.music_get_members(band_name)
|
||||
|
||||
|
||||
def get_artist_birth_place(artist_name: str) -> dict:
|
||||
"""Get the birthplace of an artist."""
|
||||
api = CRAG()
|
||||
return api.music_get_artist_birth_place(artist_name)
|
||||
|
||||
|
||||
def get_billboard_rank_date(rank: int, date: str = None) -> dict:
|
||||
"""Get Billboard ranking for a specific rank and date."""
|
||||
api = CRAG()
|
||||
rank = int(rank)
|
||||
return api.music_get_billboard_rank_date(rank, date)
|
||||
|
||||
|
||||
def get_song_release_date(song_name: str) -> dict:
|
||||
"""Get the release date of a song."""
|
||||
api = CRAG()
|
||||
return api.music_get_song_release_date(song_name)
|
||||
@@ -1,2 +1,5 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
duckduckgo_search:
|
||||
callable_api: ddg-search
|
||||
BIN
AudioQnA/assets/img/audio_ui.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
AudioQnA/assets/img/audio_ui_record.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
AudioQnA/assets/img/audioqna.jpg
Normal file
|
After Width: | Height: | Size: 48 KiB |
33
AudioQnA/docker/Dockerfile
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
FROM python:3.11-slim
|
||||
|
||||
RUN apt-get update -y && apt-get install -y --no-install-recommends --fix-missing \
|
||||
libgl1-mesa-glx \
|
||||
libjemalloc-dev \
|
||||
vim \
|
||||
git
|
||||
|
||||
RUN useradd -m -s /bin/bash user && \
|
||||
mkdir -p /home/user && \
|
||||
chown -R user /home/user/
|
||||
|
||||
WORKDIR /home/user/
|
||||
RUN git clone https://github.com/opea-project/GenAIComps.git
|
||||
|
||||
WORKDIR /home/user/GenAIComps
|
||||
RUN pip install --no-cache-dir --upgrade pip && \
|
||||
pip install --no-cache-dir -r /home/user/GenAIComps/requirements.txt
|
||||
|
||||
COPY ./audioqna.py /home/user/audioqna.py
|
||||
|
||||
ENV PYTHONPATH=$PYTHONPATH:/home/user/GenAIComps
|
||||
|
||||
USER user
|
||||
|
||||
WORKDIR /home/user
|
||||
|
||||
ENTRYPOINT ["python", "audioqna.py"]
|
||||
58
AudioQnA/docker/audioqna.py
Normal file
@@ -0,0 +1,58 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from comps import AudioQnAGateway, MicroService, ServiceOrchestrator, ServiceType
|
||||
|
||||
MEGA_SERVICE_HOST_IP = os.getenv("MEGA_SERVICE_HOST_IP", "0.0.0.0")
|
||||
MEGA_SERVICE_PORT = int(os.getenv("MEGA_SERVICE_PORT", 8888))
|
||||
ASR_SERVICE_HOST_IP = os.getenv("ASR_SERVICE_HOST_IP", "0.0.0.0")
|
||||
ASR_SERVICE_PORT = int(os.getenv("ASR_SERVICE_PORT", 9099))
|
||||
LLM_SERVICE_HOST_IP = os.getenv("LLM_SERVICE_HOST_IP", "0.0.0.0")
|
||||
LLM_SERVICE_PORT = int(os.getenv("LLM_SERVICE_PORT", 9000))
|
||||
TTS_SERVICE_HOST_IP = os.getenv("TTS_SERVICE_HOST_IP", "0.0.0.0")
|
||||
TTS_SERVICE_PORT = int(os.getenv("TTS_SERVICE_PORT", 9088))
|
||||
|
||||
|
||||
class AudioQnAService:
|
||||
def __init__(self, host="0.0.0.0", port=8000):
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.megaservice = ServiceOrchestrator()
|
||||
|
||||
def add_remote_service(self):
|
||||
asr = MicroService(
|
||||
name="asr",
|
||||
host=ASR_SERVICE_HOST_IP,
|
||||
port=ASR_SERVICE_PORT,
|
||||
endpoint="/v1/audio/transcriptions",
|
||||
use_remote_service=True,
|
||||
service_type=ServiceType.ASR,
|
||||
)
|
||||
llm = MicroService(
|
||||
name="llm",
|
||||
host=LLM_SERVICE_HOST_IP,
|
||||
port=LLM_SERVICE_PORT,
|
||||
endpoint="/v1/chat/completions",
|
||||
use_remote_service=True,
|
||||
service_type=ServiceType.LLM,
|
||||
)
|
||||
tts = MicroService(
|
||||
name="tts",
|
||||
host=TTS_SERVICE_HOST_IP,
|
||||
port=TTS_SERVICE_PORT,
|
||||
endpoint="/v1/audio/speech",
|
||||
use_remote_service=True,
|
||||
service_type=ServiceType.TTS,
|
||||
)
|
||||
self.megaservice.add(asr).add(llm).add(tts)
|
||||
self.megaservice.flow_to(asr, llm)
|
||||
self.megaservice.flow_to(llm, tts)
|
||||
self.gateway = AudioQnAGateway(megaservice=self.megaservice, host="0.0.0.0", port=self.port)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
audioqna = AudioQnAService(host=MEGA_SERVICE_HOST_IP, port=MEGA_SERVICE_PORT)
|
||||
audioqna.add_remote_service()
|
||||
54
AudioQnA/docker/docker_build_compose.yaml
Normal file
@@ -0,0 +1,54 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
services:
|
||||
audioqna:
|
||||
build:
|
||||
args:
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
no_proxy: ${no_proxy}
|
||||
dockerfile: ./Dockerfile
|
||||
image: ${REGISTRY:-opea}/audioqna:${TAG:-latest}
|
||||
whisper-gaudi:
|
||||
build:
|
||||
context: GenAIComps
|
||||
dockerfile: comps/asr/whisper/Dockerfile_hpu
|
||||
extends: audioqna
|
||||
image: ${REGISTRY:-opea}/whisper-gaudi:${TAG:-latest}
|
||||
whisper:
|
||||
build:
|
||||
context: GenAIComps
|
||||
dockerfile: comps/asr/whisper/Dockerfile
|
||||
extends: audioqna
|
||||
image: ${REGISTRY:-opea}/whisper:${TAG:-latest}
|
||||
asr:
|
||||
build:
|
||||
context: GenAIComps
|
||||
dockerfile: comps/asr/Dockerfile
|
||||
extends: audioqna
|
||||
image: ${REGISTRY:-opea}/asr:${TAG:-latest}
|
||||
llm-tgi:
|
||||
build:
|
||||
context: GenAIComps
|
||||
dockerfile: comps/llms/text-generation/tgi/Dockerfile
|
||||
extends: audioqna
|
||||
image: ${REGISTRY:-opea}/llm-tgi:${TAG:-latest}
|
||||
speecht5-gaudi:
|
||||
build:
|
||||
context: GenAIComps
|
||||
dockerfile: comps/tts/speecht5/Dockerfile_hpu
|
||||
extends: audioqna
|
||||
image: ${REGISTRY:-opea}/speecht5-gaudi:${TAG:-latest}
|
||||
speecht5:
|
||||
build:
|
||||
context: GenAIComps
|
||||
dockerfile: comps/tts/speecht5/Dockerfile
|
||||
extends: audioqna
|
||||
image: ${REGISTRY:-opea}/speecht5:${TAG:-latest}
|
||||
tts:
|
||||
build:
|
||||
context: GenAIComps
|
||||
dockerfile: comps/tts/Dockerfile
|
||||
extends: audioqna
|
||||
image: ${REGISTRY:-opea}/tts:${TAG:-latest}
|
||||
135
AudioQnA/docker/gaudi/README.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Build Mega Service of AudioQnA on Gaudi
|
||||
|
||||
This document outlines the deployment process for a AudioQnA application utilizing the [GenAIComps](https://github.com/opea-project/GenAIComps.git) microservice pipeline on Intel Gaudi server.
|
||||
|
||||
## 🚀 Build Docker images
|
||||
|
||||
### 1. Source Code install GenAIComps
|
||||
|
||||
```bash
|
||||
git clone https://github.com/opea-project/GenAIComps.git
|
||||
cd GenAIComps
|
||||
```
|
||||
|
||||
### 2. Build ASR Image
|
||||
|
||||
```bash
|
||||
docker build -t opea/whisper-gaudi:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/asr/whisper/Dockerfile_hpu .
|
||||
|
||||
|
||||
docker build -t opea/asr:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/asr/Dockerfile .
|
||||
```
|
||||
|
||||
### 3. Build LLM Image
|
||||
|
||||
```bash
|
||||
docker build --no-cache -t opea/llm-tgi:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/llms/text-generation/tgi/Dockerfile .
|
||||
```
|
||||
|
||||
### 4. Build TTS Image
|
||||
|
||||
```bash
|
||||
docker build -t opea/speecht5-gaudi:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/tts/speecht5/Dockerfile_hpu .
|
||||
|
||||
docker build -t opea/tts:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f comps/tts/Dockerfile .
|
||||
```
|
||||
|
||||
### 6. Build MegaService Docker Image
|
||||
|
||||
To construct the Mega Service, we utilize the [GenAIComps](https://github.com/opea-project/GenAIComps.git) microservice pipeline within the `audioqna.py` Python script. Build the MegaService Docker image using the command below:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/opea-project/GenAIExamples.git
|
||||
cd GenAIExamples/AudioQnA/docker
|
||||
docker build --no-cache -t opea/audioqna:latest --build-arg https_proxy=$https_proxy --build-arg http_proxy=$http_proxy -f Dockerfile .
|
||||
```
|
||||
|
||||
Then run the command `docker images`, you will have following images ready:
|
||||
|
||||
1. `opea/whisper-gaudi:latest`
|
||||
2. `opea/asr:latest`
|
||||
3. `opea/llm-tgi:latest`
|
||||
4. `opea/speecht5-gaudi:latest`
|
||||
5. `opea/tts:latest`
|
||||
6. `opea/audioqna:latest`
|
||||
|
||||
## 🚀 Set the environment variables
|
||||
|
||||
Before starting the services with `docker compose`, you have to recheck the following environment variables.
|
||||
|
||||
```bash
|
||||
export host_ip=<your External Public IP> # export host_ip=$(hostname -I | awk '{print $1}')
|
||||
export HUGGINGFACEHUB_API_TOKEN=<your HF token>
|
||||
|
||||
export TGI_LLM_ENDPOINT=http://$host_ip:3006
|
||||
export LLM_MODEL_ID=Intel/neural-chat-7b-v3-3
|
||||
|
||||
export ASR_ENDPOINT=http://$host_ip:7066
|
||||
export TTS_ENDPOINT=http://$host_ip:7055
|
||||
|
||||
export MEGA_SERVICE_HOST_IP=${host_ip}
|
||||
export ASR_SERVICE_HOST_IP=${host_ip}
|
||||
export TTS_SERVICE_HOST_IP=${host_ip}
|
||||
export LLM_SERVICE_HOST_IP=${host_ip}
|
||||
|
||||
export ASR_SERVICE_PORT=3001
|
||||
export TTS_SERVICE_PORT=3002
|
||||
export LLM_SERVICE_PORT=3007
|
||||
```
|
||||
|
||||
## 🚀 Start the MegaService
|
||||
|
||||
```bash
|
||||
cd GenAIExamples/AudioQnA/docker/gaudi/
|
||||
TAG=v0.9 docker compose up -d
|
||||
```
|
||||
|
||||
## 🚀 Test MicroServices
|
||||
|
||||
```bash
|
||||
# whisper service
|
||||
curl http://${host_ip}:7066/v1/asr \
|
||||
-X POST \
|
||||
-d '{"audio": "UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA"}' \
|
||||
-H 'Content-Type: application/json'
|
||||
|
||||
# asr microservice
|
||||
curl http://${host_ip}:3001/v1/audio/transcriptions \
|
||||
-X POST \
|
||||
-d '{"byte_str": "UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA"}' \
|
||||
-H 'Content-Type: application/json'
|
||||
|
||||
# tgi service
|
||||
curl http://${host_ip}:3006/generate \
|
||||
-X POST \
|
||||
-d '{"inputs":"What is Deep Learning?","parameters":{"max_new_tokens":17, "do_sample": true}}' \
|
||||
-H 'Content-Type: application/json'
|
||||
|
||||
# llm microservice
|
||||
curl http://${host_ip}:3007/v1/chat/completions\
|
||||
-X POST \
|
||||
-d '{"query":"What is Deep Learning?","max_new_tokens":17,"top_k":10,"top_p":0.95,"typical_p":0.95,"temperature":0.01,"repetition_penalty":1.03,"streaming":false}' \
|
||||
-H 'Content-Type: application/json'
|
||||
|
||||
# speecht5 service
|
||||
curl http://${host_ip}:7055/v1/tts \
|
||||
-X POST \
|
||||
-d '{"text": "Who are you?"}' \
|
||||
-H 'Content-Type: application/json'
|
||||
|
||||
# tts microservice
|
||||
curl http://${host_ip}:3002/v1/audio/speech \
|
||||
-X POST \
|
||||
-d '{"text": "Who are you?"}' \
|
||||
-H 'Content-Type: application/json'
|
||||
|
||||
```
|
||||
|
||||
## 🚀 Test MegaService
|
||||
|
||||
```bash
|
||||
curl http://${host_ip}:3008/v1/audioqna \
|
||||
-X POST \
|
||||
-d '{"audio": "UklGRigAAABXQVZFZm10IBIAAAABAAEARKwAAIhYAQACABAAAABkYXRhAgAAAAEA", "max_tokens":64}' \
|
||||
-H 'Content-Type: application/json'
|
||||
```
|
||||
114
AudioQnA/docker/gaudi/compose.yaml
Normal file
@@ -0,0 +1,114 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
services:
|
||||
whisper-service:
|
||||
image: ${REGISTRY:-opea}/whisper-gaudi:${TAG:-latest}
|
||||
container_name: whisper-service
|
||||
ports:
|
||||
- "7066:7066"
|
||||
ipc: host
|
||||
environment:
|
||||
no_proxy: ${no_proxy}
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
HABANA_VISIBLE_DEVICES: all
|
||||
OMPI_MCA_btl_vader_single_copy_mechanism: none
|
||||
runtime: habana
|
||||
cap_add:
|
||||
- SYS_NICE
|
||||
restart: unless-stopped
|
||||
asr:
|
||||
image: ${REGISTRY:-opea}/asr:${TAG:-latest}
|
||||
container_name: asr-service
|
||||
ports:
|
||||
- "3001:9099"
|
||||
ipc: host
|
||||
environment:
|
||||
ASR_ENDPOINT: ${ASR_ENDPOINT}
|
||||
speecht5-service:
|
||||
image: ${REGISTRY:-opea}/speecht5-gaudi:${TAG:-latest}
|
||||
container_name: speecht5-service
|
||||
ports:
|
||||
- "7055:7055"
|
||||
ipc: host
|
||||
environment:
|
||||
no_proxy: ${no_proxy}
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
HABANA_VISIBLE_DEVICES: all
|
||||
OMPI_MCA_btl_vader_single_copy_mechanism: none
|
||||
runtime: habana
|
||||
cap_add:
|
||||
- SYS_NICE
|
||||
restart: unless-stopped
|
||||
tts:
|
||||
image: ${REGISTRY:-opea}/tts:${TAG:-latest}
|
||||
container_name: tts-service
|
||||
ports:
|
||||
- "3002:9088"
|
||||
ipc: host
|
||||
environment:
|
||||
TTS_ENDPOINT: ${TTS_ENDPOINT}
|
||||
tgi-service:
|
||||
image: ghcr.io/huggingface/tgi-gaudi:2.0.1
|
||||
container_name: tgi-gaudi-server
|
||||
ports:
|
||||
- "3006:80"
|
||||
volumes:
|
||||
- "./data:/data"
|
||||
environment:
|
||||
no_proxy: ${no_proxy}
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
HF_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||
HF_HUB_DISABLE_PROGRESS_BARS: 1
|
||||
HF_HUB_ENABLE_HF_TRANSFER: 0
|
||||
HABANA_VISIBLE_DEVICES: all
|
||||
OMPI_MCA_btl_vader_single_copy_mechanism: none
|
||||
runtime: habana
|
||||
cap_add:
|
||||
- SYS_NICE
|
||||
ipc: host
|
||||
command: --model-id ${LLM_MODEL_ID} --max-input-length 1024 --max-total-tokens 2048
|
||||
llm:
|
||||
image: ${REGISTRY:-opea}/llm-tgi:${TAG:-latest}
|
||||
container_name: llm-tgi-gaudi-server
|
||||
depends_on:
|
||||
- tgi-service
|
||||
ports:
|
||||
- "3007:9000"
|
||||
ipc: host
|
||||
environment:
|
||||
no_proxy: ${no_proxy}
|
||||
http_proxy: ${http_proxy}
|
||||
https_proxy: ${https_proxy}
|
||||
TGI_LLM_ENDPOINT: ${TGI_LLM_ENDPOINT}
|
||||
HUGGINGFACEHUB_API_TOKEN: ${HUGGINGFACEHUB_API_TOKEN}
|
||||
restart: unless-stopped
|
||||
audioqna-gaudi-backend-server:
|
||||
image: ${REGISTRY:-opea}/audioqna:${TAG:-latest}
|
||||
container_name: audioqna-gaudi-backend-server
|
||||
depends_on:
|
||||
- asr
|
||||
- llm
|
||||
- tts
|
||||
ports:
|
||||
- "3008:8888"
|
||||
environment:
|
||||
- no_proxy=${no_proxy}
|
||||
- https_proxy=${https_proxy}
|
||||
- http_proxy=${http_proxy}
|
||||
- MEGA_SERVICE_HOST_IP=${MEGA_SERVICE_HOST_IP}
|
||||
- ASR_SERVICE_HOST_IP=${ASR_SERVICE_HOST_IP}
|
||||
- ASR_SERVICE_PORT=${ASR_SERVICE_PORT}
|
||||
- LLM_SERVICE_HOST_IP=${LLM_SERVICE_HOST_IP}
|
||||
- LLM_SERVICE_PORT=${LLM_SERVICE_PORT}
|
||||
- TTS_SERVICE_HOST_IP=${TTS_SERVICE_HOST_IP}
|
||||
- TTS_SERVICE_PORT=${TTS_SERVICE_PORT}
|
||||
ipc: host
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
default:
|
||||
driver: bridge
|
||||
26
AudioQnA/docker/ui/docker/Dockerfile
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (C) 2024 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# Use node 20.11.1 as the base image
|
||||
FROM node:20.11.1
|
||||
|
||||
# Update package manager and install Git
|
||||
RUN apt-get update -y && apt-get install -y git
|
||||
|
||||
# Copy the front-end code repository
|
||||
COPY svelte /home/user/svelte
|
||||
|
||||
# Set the working directory
|
||||
WORKDIR /home/user/svelte
|
||||
|
||||
# Install front-end dependencies
|
||||
RUN npm install
|
||||
|
||||
# Build the front-end application
|
||||
RUN npm run build
|
||||
|
||||
# Expose the port of the front-end application
|
||||
EXPOSE 5173
|
||||
|
||||
# Run the front-end application in preview mode
|
||||
CMD ["npm", "run", "preview", "--", "--port", "5173", "--host", "0.0.0.0"]
|
||||
10
AudioQnA/docker/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
|
||||
2
AudioQnA/docker/ui/svelte/.env
Normal file
@@ -0,0 +1,2 @@
|
||||
CHAT_URL = 'http://backend_address:3008/v1/audioqna'
|
||||
|
||||
13
AudioQnA/docker/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
|
||||
20
AudioQnA/docker/ui/svelte/.eslintrc.cjs
Normal file
@@ -0,0 +1,20 @@
|
||||
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
AudioQnA/docker/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
|
||||
1
AudioQnA/docker/ui/svelte/.prettierrc
Normal file
@@ -0,0 +1 @@
|
||||
{"pluginSearchDirs": ["."], "overrides": [{"files": "*.svelte", "options": {"parser": "svelte"}}]}
|
||||
29
AudioQnA/docker/ui/svelte/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# AudioQnA
|
||||
|
||||
## 📸 Project Screenshots
|
||||
|
||||

|
||||

|
||||
|
||||
## 🧐 Features
|
||||
|
||||
Here're some of the project's features:
|
||||
|
||||
- Start a Talking Chat:Initiate voice chat, able to input voice content, and customize the conversation sound based on the uploaded file.
|
||||
- Scroll to Bottom: The chat automatically slides to the bottom.
|
||||
|
||||
## 🛠️ Get it Running
|
||||
|
||||
1. Clone the repo.
|
||||
|
||||
2. cd command to the current folder.
|
||||
|
||||
3. Modify the required .env variables.
|
||||
|
||||
```
|
||||
CHAT_URL = ''
|
||||
```
|
||||
|
||||
4. Execute `npm install` to install the corresponding dependencies.
|
||||
|
||||
5. Execute `npm run dev` in both environments
|
||||
57
AudioQnA/docker/ui/svelte/package.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "sveltekit-auth-example",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
||||
"lint": "prettier --check . && eslint .",
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@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.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",
|
||||
"neverthrow": "5.0.0",
|
||||
"pocketbase": "0.7.0",
|
||||
"postcss": "^8.4.23",
|
||||
"postcss-load-config": "^4.0.1",
|
||||
"postcss-preset-env": "^8.3.2",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier-plugin-svelte": "^2.7.0",
|
||||
"prettier-plugin-tailwindcss": "^0.3.0",
|
||||
"svelte": "^3.59.1",
|
||||
"svelte-check": "^2.7.1",
|
||||
"svelte-fa": "3.0.3",
|
||||
"svelte-preprocess": "^4.10.7",
|
||||
"tailwindcss": "^3.1.5",
|
||||
"ts-pattern": "4.0.5",
|
||||
"tslib": "^2.3.1",
|
||||
"typescript": "^4.7.4",
|
||||
"vite": "^4.3.9"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"echarts": "^5.4.2",
|
||||
"flowbite-svelte": "^0.38.5",
|
||||
"fuse": "^0.4.0",
|
||||
"fuse.js": "^6.6.2",
|
||||
"ramda": "^0.29.0",
|
||||
"sse.js": "^0.6.1",
|
||||
"svelte-notifications": "^0.9.98"
|
||||
}
|
||||
}
|
||||
13
AudioQnA/docker/ui/svelte/postcss.config.cjs
Normal file
@@ -0,0 +1,13 @@
|
||||
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;
|
||||
30
AudioQnA/docker/ui/svelte/src/app.d.ts
vendored
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.
|
||||
|
||||
// See: https://kit.svelte.dev/docs/types#app
|
||||
// import { Result} from "neverthrow";
|
||||
|
||||
declare namespace App {
|
||||
interface Locals {
|
||||
user?: User;
|
||||
}
|
||||
// interface PageData { }
|
||||
// interface PageError {}
|
||||
// interface Platform {}
|
||||
}
|
||||
|
||||
interface ChatMessage {
|
||||
role: string;
|
||||
content: string;
|
||||
}
|
||||
28
AudioQnA/docker/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" />
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
<body>
|
||||
<div>%sveltekit.body%</div>
|
||||
</body>
|
||||
</html>
|
||||
82
AudioQnA/docker/ui/svelte/src/app.postcss
Normal file
@@ -0,0 +1,82 @@
|
||||
/* Write your global styles here, in PostCSS syntax */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.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: #0071c5;
|
||||
}
|
||||
|
||||
.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%
|
||||
}
|
||||
BIN
AudioQnA/docker/ui/svelte/src/lib/assets/icons/png/audio1.png
Normal file
|
After Width: | Height: | Size: 762 B |
BIN
AudioQnA/docker/ui/svelte/src/lib/assets/icons/png/audio2.png
Normal file
|
After Width: | Height: | Size: 752 B |
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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-4 h-4 text-gray-500';
|
||||
</script>
|
||||
|
||||
<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="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0l3.181 3.183a8.25 8.25 0 0013.803-3.7M4.031 9.865a8.25 8.25 0 0113.803-3.7l3.181 3.182m0-4.991v4.99"
|
||||
/>
|
||||
</svg>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!--
|
||||
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 t="1713432596850" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7421" width="32" height="32"><path d="M399.837 3.809h244.886v1016.381h-244.886v-1016.381z" fill="#231915" p-id="7422"></path></svg>
|
||||
|
After Width: | Height: | Size: 838 B |
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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-6 h-6`;
|
||||
</script>
|
||||
|
||||
<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="M2.25 12.76c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.076-4.076a1.526 1.526 0 011.037-.443 48.282 48.282 0 005.68-.494c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z"
|
||||
/>
|
||||
</svg>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!--
|
||||
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="w-6 h-6" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" fill="#797a9f"><path d="M512 64c259.2 0 469.333333 200.576 469.333333 448s-210.133333 448-469.333333 448a484.48 484.48 0 0 1-232.725333-58.88l-116.394667 50.645333a42.666667 42.666667 0 0 1-58.517333-49.002666l29.76-125.013334C76.629333 703.402667 42.666667 611.477333 42.666667 512 42.666667 264.576 252.8 64 512 64z m0 64C287.488 128 106.666667 300.586667 106.666667 512c0 79.573333 25.557333 155.434667 72.554666 219.285333l5.525334 7.317334 18.709333 24.192-26.965333 113.237333 105.984-46.08 27.477333 15.018667C370.858667 878.229333 439.978667 896 512 896c224.512 0 405.333333-172.586667 405.333333-384S736.512 128 512 128z m-157.696 341.333333a42.666667 42.666667 0 1 1 0 85.333334 42.666667 42.666667 0 0 1 0-85.333334z m159.018667 0a42.666667 42.666667 0 1 1 0 85.333334 42.666667 42.666667 0 0 1 0-85.333334z m158.997333 0a42.666667 42.666667 0 1 1 0 85.333334 42.666667 42.666667 0 0 1 0-85.333334z"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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-6 h-6`;
|
||||
</script>
|
||||
|
||||
<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="M4.5 12.75l6 6 9-13.5"
|
||||
/>
|
||||
</svg>
|
||||
@@ -0,0 +1,49 @@
|
||||
<!--
|
||||
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
|
||||
aria-hidden="true"
|
||||
class="intel-brand-logo"
|
||||
width="75"
|
||||
height="50"
|
||||
viewBox="0 0 103 42"
|
||||
>
|
||||
<g fill-rule="evenodd" transform="translate(.363 .363)">
|
||||
<rect
|
||||
class="spark"
|
||||
width="7.245"
|
||||
height="7.245"
|
||||
x=".134"
|
||||
y=".291"
|
||||
fill="#00c7fd"
|
||||
transform="translate(.503 .874)"
|
||||
></rect>
|
||||
<path
|
||||
fill-rule="nonzero"
|
||||
class="letters"
|
||||
d="M61.1464956,23.3063694 C61.144586,21.3987261 63.3363057,18.0675159 68.0579618,18.0624204 C72.7802548,18.0624204 74.9751592,21.3904459 74.9751592,23.2980892 L61.1464956,23.3063694 Z M81.5649682,25.6974522 C81.5649682,23.8292994 81.2312102,22.0566879 80.5732484,20.4273885 C79.9159236,18.8019108 78.9859873,17.3541401 77.8095541,16.1254777 C76.6343949,14.8987261 75.2057325,13.9254777 73.5630573,13.233758 C71.9197452,12.5420382 70.0853503,12.1910828 68.110828,12.1910828 C66.2426752,12.1910828 64.4624204,12.5503185 62.8184713,13.2598726 C61.1732484,13.9694268 59.7254777,14.9433121 58.5146497,16.1541401 C57.3031847,17.366242 56.3292994,18.8140127 55.6197452,20.4579618 C54.910828,22.1 54.5515924,23.8808917 54.5515924,25.7503185 C54.5515924,27.6210191 54.8936306,29.4025478 55.5681529,31.0458599 C56.2433121,32.6910828 57.1910828,34.1382166 58.3834395,35.3471338 C59.5770701,36.5585987 61.0414013,37.5318471 62.7369427,38.2407643 C64.4343949,38.9503185 66.3133758,39.3095541 68.322293,39.3095541 C74.1305732,39.3095541 77.7535032,36.6675159 79.9159236,34.1955414 L74.9751592,30.4318471 C73.933758,31.6675159 71.4624204,33.343949 68.3751592,33.343949 C66.4382166,33.343949 64.843949,32.8955414 63.6356688,32.011465 C62.4261146,31.1273885 61.5923567,29.9101911 61.1592357,28.3936306 L61.0898089,28.1515924 L81.5649682,28.1515924 L81.5649682,25.6974522 Z M34.2031847,15.2859873 C32.3012739,13.233121 29.6146497,12.1910828 26.2171975,12.1910828 C24.5789809,12.1910828 23.0636943,12.5286624 21.7133758,13.1942675 C20.3624204,13.8605096 19.2146497,14.7961783 18.3019108,15.9745223 L17.9280255,16.4573248 L17.9254777,16.0229299 L17.9254777,12.7197452 L11.1541401,12.7197452 L11.1541401,38.7808917 L17.9783439,38.7808917 L17.9783439,24.8968153 L17.9840764,25.8605096 C17.9840764,25.7012739 17.9866242,25.5452229 17.9910828,25.3904459 C18.0611465,22.956051 18.6694268,21.1394904 19.8019108,19.9859873 C21.0095541,18.7566879 22.4757962,18.133758 24.1592357,18.133758 C26.1401274,18.133758 27.6522293,18.7407643 28.6535032,19.9369427 C29.633758,21.1101911 30.1350318,22.7910828 30.1458599,24.9324841 L30.1464968,24.9324841 L30.1464968,38.7808917 L37.0751592,38.7808917 L37.0751592,23.9859873 C37.0751592,20.2719745 36.1089172,17.3452229 34.2031847,15.2859873 M92.0076433,0.557324841 L85.1426752,0.557324841 L85.1426752,38.7808917 L92.0076433,38.7808917 L92.0076433,0.557324841 Z M52.6592357,39.0452229 L52.6592357,32.656051 C51.6477707,32.6496815 50.8127389,32.5955414 50.1751592,32.4955414 C49.466879,32.3834395 48.9248408,32.1433121 48.5636943,31.7815287 C48.2019108,31.4197452 47.9617834,30.8955414 47.8496815,30.2235669 C47.7426752,29.5815287 47.688535,28.7343949 47.688535,27.7070064 L47.688535,18.5910828 L52.6592357,18.5910828 L52.6592357,12.7197452 L47.688535,12.7197452 L47.688535,2.56624204 L40.8229299,2.56624204 L40.8229299,27.7598726 C40.8229299,29.8847134 41.0076433,31.6929936 41.3726115,33.133758 C41.733121,34.5573248 42.3477707,35.7203822 43.2019108,36.5904459 C44.0541401,37.4611465 45.1821656,38.0936306 46.5535032,38.4707006 C47.9382166,38.8522293 49.7,39.0452229 51.7910828,39.0452229 L52.6592357,39.0452229 Z M7.15031847,12.7197452 L0.285350318,12.7197452 L0.285350318,38.7808917 L7.15031847,38.7808917 L7.15031847,12.7197452 Z"
|
||||
transform="translate(.541 .08)"
|
||||
fill="#fff"
|
||||
></path>
|
||||
<path
|
||||
fill-rule="nonzero"
|
||||
class="regmark"
|
||||
fill="#fff"
|
||||
d="M3.18471338,2.75477707 C3.10254777,2.76178344 3.02101911,2.76496815 2.9388535,2.76496815 L2.54904459,2.76496815 L2.54904459,1.95159236 L2.9388535,1.95159236 C3.02101911,1.95159236 3.10254777,1.95414013 3.18471338,1.95859873 C3.26687898,1.96305732 3.34076433,1.97898089 3.40700637,2.00636943 C3.47261146,2.03375796 3.52611465,2.07515924 3.56751592,2.12993631 C3.60828025,2.18407643 3.62866242,2.25923567 3.62866242,2.35477707 C3.62866242,2.45031847 3.60828025,2.52611465 3.56751592,2.58089172 C3.52611465,2.63566879 3.47261146,2.67579618 3.40700637,2.70318471 C3.34076433,2.73057325 3.26687898,2.7477707 3.18471338,2.75477707 M3.47197452,3.17452229 C3.67006369,3.1522293 3.83503185,3.07707006 3.9656051,2.94968153 C4.09617834,2.82165605 4.16178344,2.63057325 4.16178344,2.37515924 C4.16178344,2.09299363 4.07834395,1.87643312 3.91273885,1.72611465 C3.74585987,1.57579618 3.48789809,1.50063694 3.13694268,1.50063694 L2.01656051,1.50063694 L2.01656051,4.40509554 L2.54904459,4.40509554 L2.54904459,3.21592357 L2.9388535,3.21592357 L3.66305732,4.40509554 L4.22292994,4.40509554 L3.47197452,3.17452229 Z M4.92038217,3.78280255 C4.81082803,4.03821656 4.66178344,4.25987261 4.47261146,4.44904459 C4.28343949,4.63821656 4.0611465,4.78726115 3.80636943,4.89681529 C3.55159236,5.00573248 3.28025478,5.06050955 2.99299363,5.06050955 C2.70636943,5.06050955 2.43503185,5.00573248 2.18025478,4.89681529 C1.92484076,4.78726115 1.70318471,4.63821656 1.51401274,4.44904459 C1.32484076,4.25987261 1.17579618,4.03821656 1.06624204,3.78280255 C0.956687898,3.52802548 0.902547771,3.2566879 0.902547771,2.97006369 C0.902547771,2.68280255 0.956687898,2.41210191 1.06624204,2.15732484 C1.17579618,1.90191083 1.32484076,1.67961783 1.51401274,1.49044586 C1.70318471,1.30191083 1.92484076,1.1522293 2.18025478,1.04267516 C2.43503185,0.933757962 2.70636943,0.878980892 2.99299363,0.878980892 C3.28025478,0.878980892 3.55159236,0.933757962 3.80636943,1.04267516 C4.0611465,1.1522293 4.28343949,1.30191083 4.47261146,1.49044586 C4.66178344,1.67961783 4.81082803,1.90191083 4.92038217,2.15732484 C5.02929936,2.41210191 5.08407643,2.68280255 5.08407643,2.97006369 C5.08407643,3.2566879 5.02929936,3.52802548 4.92038217,3.78280255 M5.33375796,1.98280255 C5.19936306,1.67515924 5.01656051,1.40636943 4.78726115,1.17579618 C4.5566879,0.945859873 4.28789809,0.76433121 3.98089172,0.629299363 C3.67324841,0.494904459 3.34394904,0.428025478 2.99299363,0.428025478 C2.64267516,0.428025478 2.3133758,0.494904459 2.00573248,0.629299363 C1.69872611,0.76433121 1.42993631,0.945859873 1.2,1.17579618 C0.969426752,1.40636943 0.787261146,1.67515924 0.652866242,1.98280255 C0.518471338,2.29044586 0.451592357,2.61910828 0.451592357,2.97006369 C0.451592357,3.32101911 0.518471338,3.64968153 0.652866242,3.95732484 C0.787261146,4.26433121 0.969426752,4.53375796 1.2,4.76305732 C1.42993631,4.99363057 1.69872611,5.17579618 2.00573248,5.31019108 C2.3133758,5.44458599 2.64267516,5.51146497 2.99299363,5.51146497 C3.34394904,5.51146497 3.67324841,5.44458599 3.98089172,5.31019108 C4.28789809,5.17579618 4.5566879,4.99363057 4.78726115,4.76305732 C5.01656051,4.53375796 5.19936306,4.26433121 5.33375796,3.95732484 C5.46751592,3.64968153 5.53503185,3.32101911 5.53503185,2.97006369 C5.53503185,2.61910828 5.46751592,2.29044586 5.33375796,1.98280255"
|
||||
transform="translate(95.036 34)"
|
||||
></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.5 KiB |
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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="animate-spin mx-auto h-5 w-5 text-gray-500"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
>
|
||||
<circle
|
||||
class="opacity-25"
|
||||
cx="12"
|
||||
cy="12"
|
||||
r="10"
|
||||
stroke="currentColor"
|
||||
stroke-width="4"
|
||||
/>
|
||||
<path
|
||||
class="opacity-75"
|
||||
fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -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.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
import PersonOutlined from "$lib/assets/icons/svelte/portrait.svelte";
|
||||
import AssistantIcon from "$lib/assets/icons/svelte/assistant.svelte";
|
||||
export let role: string;
|
||||
|
||||
</script>
|
||||
|
||||
{#if role === "Human"}
|
||||
<PersonOutlined />
|
||||
{:else}
|
||||
<AssistantIcon />
|
||||
{/if}
|
||||
@@ -0,0 +1,38 @@
|
||||
<!--
|
||||
Copyright (c) 2024 Intel Corporation
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
|
||||
<script lang="ts">
|
||||
export let overrideClasses = '';
|
||||
|
||||
const classes = overrideClasses
|
||||
? overrideClasses
|
||||
: 'w-6 h-6 text-gray-500 dark:text-gray-400';
|
||||
</script>
|
||||
|
||||
<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="M12 4.5v15m7.5-7.5h-15"
|
||||
/>
|
||||
</svg>
|
||||
@@ -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
|
||||
t="1689304948638"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="6750"
|
||||
width="32"
|
||||
height="32"
|
||||
><path
|
||||
d="M510.59375 62.703125c124.453125 0 225 99.140625 225 221.484375s-100.546875 221.484375-225 221.484375-225-99.140625-225-221.484375S386.84375 62.703125 510.59375 62.703125zM412.859375 566.140625H610.4375c169.453125 0 306.5625 111.796875 306.5625 278.4375v19.6875c0 65.390625-137.109375 97.03125-306.5625 97.03125H412.859375c-169.453125 0-306.5625-29.53125-306.5625-97.03125v-19.6875c0-166.640625 137.8125-278.4375 306.5625-278.4375z"
|
||||
p-id="6751"
|
||||
fill="#ffffff"
|
||||
/></svg
|
||||
>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,179 @@
|
||||
<!--
|
||||
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="54"
|
||||
height="52"
|
||||
viewBox="0 0 54 52"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle opacity="0.1" cx="27" cy="26" r="25" fill="#A6C9FF" />
|
||||
<ellipse opacity="0.36" cx="27" cy="26" rx="22" ry="22" fill="#86B6FF" />
|
||||
<g filter="url(#filter0_ddddf_9_2690)">
|
||||
<ellipse cx="27" cy="26" rx="18.3333" ry="18.3333" fill="#538DFF" />
|
||||
</g>
|
||||
<g clip-path="url(#clip0_9_2690)">
|
||||
<path
|
||||
d="M27.0319 28.5416C28.4489 28.5416 29.5976 27.3929 29.5976 25.9759V20.2324C29.5976 18.8154 28.4489 17.6667 27.0319 17.6667C25.615 17.6667 24.4662 18.8154 24.4662 20.2324V25.9828C24.4662 27.3929 25.615 28.5416 27.0319 28.5416ZM25.1541 20.2324C25.1541 19.1937 26.0002 18.3545 27.0319 18.3545C28.0637 18.3545 28.9098 19.1937 28.9098 20.2324V25.9828C28.9098 27.0146 28.0706 27.8606 27.0319 27.8606C26.0002 27.8606 25.1541 27.0215 25.1541 25.9828V20.2324Z"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M32.1427 24.1531C31.9501 24.1531 31.7988 24.3044 31.7988 24.497V25.914C31.7988 28.5072 29.7421 30.6671 27.1489 30.7084C24.5144 30.7427 22.3545 28.6104 22.3545 25.9828V24.497C22.3545 24.3044 22.2032 24.1531 22.0106 24.1531C21.818 24.1531 21.6667 24.3044 21.6667 24.497V25.914C21.6667 28.8924 24.0398 31.3618 27.0182 31.3893C28.5383 31.4031 29.914 30.7978 30.9045 29.8073C31.8813 28.8305 32.4866 27.4754 32.4866 25.9828V24.497C32.4866 24.3044 32.3284 24.1531 32.1427 24.1531Z"
|
||||
fill="#fff"
|
||||
/>
|
||||
<path
|
||||
d="M29.9278 33.6455H27.4171V31.3962H26.7293V33.6455H24.1498C23.9572 33.6455 23.8059 33.7968 23.8059 33.9894C23.8059 34.182 23.9572 34.3333 24.1498 34.3333H29.9278C30.1204 34.3333 30.2717 34.182 30.2717 33.9894C30.2717 33.7968 30.1204 33.6455 29.9278 33.6455Z"
|
||||
fill="#fff"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_ddddf_9_2690"
|
||||
x="0.666687"
|
||||
y="0.666672"
|
||||
width="52.6667"
|
||||
height="50.6667"
|
||||
filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB"
|
||||
>
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dy="4" />
|
||||
<feGaussianBlur stdDeviation="1.5" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="BackgroundImageFix"
|
||||
result="effect1_dropShadow_9_2690"
|
||||
/>
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dy="-4" />
|
||||
<feGaussianBlur stdDeviation="1.5" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="effect1_dropShadow_9_2690"
|
||||
result="effect2_dropShadow_9_2690"
|
||||
/>
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dx="4" />
|
||||
<feGaussianBlur stdDeviation="2" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="effect2_dropShadow_9_2690"
|
||||
result="effect3_dropShadow_9_2690"
|
||||
/>
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dx="-4" />
|
||||
<feGaussianBlur stdDeviation="2" />
|
||||
<feComposite in2="hardAlpha" operator="out" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.5 0"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in2="effect3_dropShadow_9_2690"
|
||||
result="effect4_dropShadow_9_2690"
|
||||
/>
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect4_dropShadow_9_2690"
|
||||
result="shape"
|
||||
/>
|
||||
<feGaussianBlur
|
||||
stdDeviation="0.5"
|
||||
result="effect5_foregroundBlur_9_2690"
|
||||
/>
|
||||
</filter>
|
||||
<linearGradient
|
||||
id="paint0_linear_9_2690"
|
||||
x1="27.0319"
|
||||
y1="17.6667"
|
||||
x2="27.0319"
|
||||
y2="28.5416"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="white" />
|
||||
<stop offset="1" stop-color="white" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint1_linear_9_2690"
|
||||
x1="27.0766"
|
||||
y1="24.1531"
|
||||
x2="27.0766"
|
||||
y2="31.3896"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="white" />
|
||||
<stop offset="1" stop-color="white" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="paint2_linear_9_2690"
|
||||
x1="27.0388"
|
||||
y1="31.3962"
|
||||
x2="27.0388"
|
||||
y2="34.3333"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop stop-color="white" />
|
||||
<stop offset="1" stop-color="white" />
|
||||
</linearGradient>
|
||||
<clipPath id="clip0_9_2690">
|
||||
<rect
|
||||
width="10.8199"
|
||||
height="16.6667"
|
||||
fill="white"
|
||||
transform="translate(21.6667 17.6667)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
@@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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-6 h-6`;
|
||||
</script>
|
||||
|
||||
<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 18L18 6M6 6l12 12"
|
||||
/>
|
||||
</svg>
|
||||
92
AudioQnA/docker/ui/svelte/src/lib/assets/icons/svg/1.svg
Normal file
@@ -0,0 +1,92 @@
|
||||
<svg viewBox="0 0 1200 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="#f3f4f6" />
|
||||
<g filter="url(#filter0_f_1_730)">
|
||||
<path
|
||||
d="M733 336C733 385.706 613.706 398 564 398C514.294 398 445.5 293.205 445.5 243.5C445.5 193.794 535.294 243.5 585 243.5C634.706 243.5 733 286.294 733 336Z"
|
||||
fill="url(#paint0_linear_1_730)" />
|
||||
<path
|
||||
d="M733 336C733 385.706 613.706 398 564 398C514.294 398 445.5 293.205 445.5 243.5C445.5 193.794 535.294 243.5 585 243.5C634.706 243.5 733 286.294 733 336Z"
|
||||
fill="url(#paint1_linear_1_730)" />
|
||||
</g>
|
||||
<g filter="url(#filter1_f_1_730)">
|
||||
<path
|
||||
d="M733 336C733 385.706 613.706 398 564 398C514.294 398 445.5 293.205 445.5 243.5C445.5 193.794 535.294 243.5 585 243.5C634.706 243.5 733 286.294 733 336Z"
|
||||
fill="url(#paint2_linear_1_730)" />
|
||||
<path
|
||||
d="M733 336C733 385.706 613.706 398 564 398C514.294 398 445.5 293.205 445.5 243.5C445.5 193.794 535.294 243.5 585 243.5C634.706 243.5 733 286.294 733 336Z"
|
||||
fill="url(#paint3_linear_1_730)" />
|
||||
</g>
|
||||
<g filter="url(#filter2_f_1_730)">
|
||||
<path
|
||||
d="M765.5 289C765.5 342.019 727.519 404 674.5 404C621.481 404 524 342.019 524 289C524 235.981 586.481 155.5 639.5 155.5C692.519 155.5 765.5 235.981 765.5 289Z"
|
||||
fill="url(#paint4_linear_1_730)" />
|
||||
</g>
|
||||
<g filter="url(#filter3_f_1_730)">
|
||||
<path
|
||||
d="M765.5 289C765.5 342.019 727.519 404 674.5 404C621.481 404 524 342.019 524 289C524 235.981 586.481 155.5 639.5 155.5C692.519 155.5 765.5 235.981 765.5 289Z"
|
||||
fill="url(#paint5_linear_1_730)" />
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay">
|
||||
<rect x="516" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="536" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="556" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="576" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="596" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="616" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="636" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="656" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="676" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_1_730" x="411.23" y="187.138" width="356.04" height="245.132" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_730" />
|
||||
</filter>
|
||||
<filter id="filter1_f_1_730" x="411.23" y="187.138" width="356.04" height="245.132" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_730" />
|
||||
</filter>
|
||||
<filter id="filter2_f_1_730" x="489.73" y="121.23" width="310.04" height="317.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_730" />
|
||||
</filter>
|
||||
<filter id="filter3_f_1_730" x="489.73" y="121.23" width="310.04" height="317.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_730" />
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_730" x1="492.606" y1="230.404" x2="618.231" y2="398"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF2E00" />
|
||||
<stop offset="1" stop-color="#1400FF" stop-opacity="0.2" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_730" x1="564" y1="218" x2="564" y2="398" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.58" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0.2" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_730" x1="492.606" y1="230.404" x2="618.231" y2="398"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF2E00" />
|
||||
<stop offset="1" stop-color="#1400FF" stop-opacity="0.2" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_1_730" x1="564" y1="218" x2="564" y2="398" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.58" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0.2" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_1_730" x1="620" y1="193" x2="620" y2="385" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.48" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0.2" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_1_730" x1="620" y1="193" x2="620" y2="385" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.48" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0.2" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
92
AudioQnA/docker/ui/svelte/src/lib/assets/icons/svg/2.svg
Normal file
@@ -0,0 +1,92 @@
|
||||
<svg viewBox="0 0 1200 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="#f3f4f6" />
|
||||
<g filter="url(#filter0_f_1_772)">
|
||||
<path
|
||||
d="M651 291.5C651 348.661 604.661 395 547.5 395C490.339 395 410 303.162 410 246C410 188.839 490.339 197.5 547.5 197.5C604.661 197.5 651 234.338 651 291.5Z"
|
||||
fill="url(#paint0_linear_1_772)" />
|
||||
<path
|
||||
d="M651 291.5C651 348.661 604.661 395 547.5 395C490.339 395 410 303.162 410 246C410 188.839 490.339 197.5 547.5 197.5C604.661 197.5 651 234.338 651 291.5Z"
|
||||
fill="url(#paint1_linear_1_772)" />
|
||||
</g>
|
||||
<g filter="url(#filter1_f_1_772)">
|
||||
<path
|
||||
d="M651 291.5C651 348.661 604.661 395 547.5 395C490.339 395 410 303.161 410 246C410 188.839 490.339 197.5 547.5 197.5C604.661 197.5 651 234.338 651 291.5Z"
|
||||
fill="url(#paint2_linear_1_772)" />
|
||||
<path
|
||||
d="M651 291.5C651 348.661 604.661 395 547.5 395C490.339 395 410 303.161 410 246C410 188.839 490.339 197.5 547.5 197.5C604.661 197.5 651 234.338 651 291.5Z"
|
||||
fill="url(#paint3_linear_1_772)" />
|
||||
</g>
|
||||
<g filter="url(#filter2_f_1_772)">
|
||||
<path
|
||||
d="M721.5 280C721.5 335.781 581.281 455.5 525.5 455.5C469.719 455.5 548.5 318.281 548.5 262.5C548.5 206.719 594.219 205.5 650 205.5C705.781 205.5 721.5 224.219 721.5 280Z"
|
||||
fill="url(#paint4_linear_1_772)" />
|
||||
</g>
|
||||
<g filter="url(#filter3_f_1_772)">
|
||||
<path
|
||||
d="M721.5 280C721.5 335.781 581.281 455.5 525.5 455.5C469.719 455.5 548.5 318.281 548.5 262.5C548.5 206.719 594.219 205.5 650 205.5C705.781 205.5 721.5 224.219 721.5 280Z"
|
||||
fill="url(#paint5_linear_1_772)" />
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay">
|
||||
<rect x="516" y="276" width="8" height="48" rx="4" fill="#f3f4f6" />
|
||||
<rect x="536" y="288" width="8" height="24" rx="4" fill="#f3f4f6" />
|
||||
<rect x="556" y="280" width="8" height="40" rx="4" fill="#f3f4f6" />
|
||||
<rect x="576" y="284" width="8" height="32" rx="4" fill="#f3f4f6" />
|
||||
<rect x="596" y="264" width="8" height="72" rx="4" fill="#f3f4f6" />
|
||||
<rect x="616" y="268" width="8" height="64" rx="4" fill="#f3f4f6" />
|
||||
<rect x="636" y="286" width="8" height="28" rx="4" fill="#f3f4f6" />
|
||||
<rect x="656" y="276" width="8" height="48" rx="4" fill="#f3f4f6" />
|
||||
<rect x="676" y="288" width="8" height="24" rx="4" fill="#f3f4f6" />
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_1_772" x="375.73" y="162.762" width="309.54" height="266.508" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_772" />
|
||||
</filter>
|
||||
<filter id="filter1_f_1_772" x="375.73" y="162.761" width="309.54" height="266.508" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_772" />
|
||||
</filter>
|
||||
<filter id="filter2_f_1_772" x="471.26" y="171.23" width="284.51" height="318.54" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_772" />
|
||||
</filter>
|
||||
<filter id="filter3_f_1_772" x="471.26" y="171.23" width="284.51" height="318.54" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_772" />
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_772" x1="465.397" y1="202.265" x2="609.865" y2="395"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF2E00" />
|
||||
<stop offset="1" stop-color="#BFB9FF" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_772" x1="547.5" y1="188" x2="547.5" y2="395" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#33C5B3" stop-opacity="0.64" />
|
||||
<stop offset="1" stop-color="#44FFC7" stop-opacity="0.6" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_772" x1="465.397" y1="202.264" x2="609.865" y2="395"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF2E00" />
|
||||
<stop offset="1" stop-color="#BFB9FF" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_1_772" x1="547.5" y1="188" x2="547.5" y2="395" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#33C5B3" stop-opacity="0.64" />
|
||||
<stop offset="1" stop-color="#44FFC7" stop-opacity="0.6" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_1_772" x1="650" y1="197" x2="650" y2="399" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#4200FF" stop-opacity="0.9" />
|
||||
<stop offset="1" stop-color="#f3f4f6" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_1_772" x1="650" y1="197" x2="650" y2="399" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#4200FF" stop-opacity="0.9" />
|
||||
<stop offset="1" stop-color="#f3f4f6" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
79
AudioQnA/docker/ui/svelte/src/lib/assets/icons/svg/3.svg
Normal file
@@ -0,0 +1,79 @@
|
||||
<svg viewBox="0 0 1200 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="#f3f4f6" />
|
||||
<g filter="url(#filter0_f_1_793)">
|
||||
<path
|
||||
d="M673 257.5C673 299.474 601.974 357.5 560 357.5C518.026 357.5 448 326.974 448 285C448 243.026 507.026 169.5 549 169.5C590.974 169.5 673 215.526 673 257.5Z"
|
||||
fill="url(#paint0_linear_1_793)" />
|
||||
</g>
|
||||
<g filter="url(#filter1_f_1_793)">
|
||||
<path
|
||||
d="M673 257.5C673 299.474 601.974 357.5 560 357.5C518.026 357.5 448 326.974 448 285C448 243.026 507.026 169.5 549 169.5C590.974 169.5 673 215.526 673 257.5Z"
|
||||
fill="url(#paint1_linear_1_793)" />
|
||||
</g>
|
||||
<g filter="url(#filter2_f_1_793)">
|
||||
<path
|
||||
d="M725.5 311.501C725.5 355.684 645.183 413.501 601 413.501C556.817 413.501 486 400.184 486 356.001C486 311.818 477.817 243.001 522 243.001C566.183 243.001 725.5 267.318 725.5 311.501Z"
|
||||
fill="url(#paint2_linear_1_793)" />
|
||||
</g>
|
||||
<g filter="url(#filter3_f_1_793)">
|
||||
<path
|
||||
d="M725.5 311.5C725.5 355.683 645.183 413.5 601 413.5C556.817 413.5 486 400.183 486 356C486 311.817 477.817 243 522 243C566.183 243 725.5 267.317 725.5 311.5Z"
|
||||
fill="url(#paint3_linear_1_793)" />
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay">
|
||||
<rect x="516" y="292" width="8" height="16" rx="4" fill="#f3f4f6" />
|
||||
<rect x="536" y="276" width="8" height="48" rx="4" fill="#f3f4f6" />
|
||||
<rect x="556" y="294" width="8" height="12" rx="4" fill="#f3f4f6" />
|
||||
<rect x="576" y="268" width="8" height="64" rx="4" fill="#f3f4f6" />
|
||||
<rect x="596" y="284" width="8" height="32" rx="4" fill="#f3f4f6" />
|
||||
<rect x="616" y="290" width="8" height="20" rx="4" fill="#f3f4f6" />
|
||||
<rect x="636" y="282" width="8" height="36" rx="4" fill="#f3f4f6" />
|
||||
<rect x="656" y="294" width="8" height="12" rx="4" fill="#f3f4f6" />
|
||||
<rect x="676" y="276" width="8" height="48" rx="4" fill="#f3f4f6" />
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_1_793" x="413.73" y="135.23" width="293.54" height="256.54" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_793" />
|
||||
</filter>
|
||||
<filter id="filter1_f_1_793" x="413.73" y="135.23" width="293.54" height="256.54" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_793" />
|
||||
</filter>
|
||||
<filter id="filter2_f_1_793" x="451.132" y="208.731" width="308.638" height="239.04"
|
||||
filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_793" />
|
||||
</filter>
|
||||
<filter id="filter3_f_1_793" x="451.132" y="208.73" width="308.638" height="239.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_793" />
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_793" x1="499.712" y1="192.474" x2="605.795" y2="334"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF00F5" />
|
||||
<stop offset="1" stop-color="#6C5FFE" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_793" x1="499.712" y1="192.474" x2="605.795" y2="334"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF00F5" />
|
||||
<stop offset="1" stop-color="#6C5FFE" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_793" x1="610" y1="259.001" x2="610" y2="419.001"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF500" stop-opacity="0.58" />
|
||||
<stop offset="1" stop-color="#9CFFED" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_1_793" x1="610" y1="259" x2="610" y2="419" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFF500" stop-opacity="0.58" />
|
||||
<stop offset="1" stop-color="#9CFFED" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
79
AudioQnA/docker/ui/svelte/src/lib/assets/icons/svg/4.svg
Normal file
@@ -0,0 +1,79 @@
|
||||
<svg viewBox="0 0 1200 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="#f3f4f6" />
|
||||
<g filter="url(#filter0_f_1_814)">
|
||||
<path
|
||||
d="M752 321.5C752 371.206 686.206 388.5 636.5 388.5C586.794 388.5 520.5 362.206 520.5 312.5C520.5 262.794 539.294 148 589 148C638.706 148 752 271.794 752 321.5Z"
|
||||
fill="url(#paint0_linear_1_814)" />
|
||||
</g>
|
||||
<g filter="url(#filter1_f_1_814)">
|
||||
<path
|
||||
d="M752 321.5C752 371.206 686.206 388.5 636.5 388.5C586.794 388.5 520.5 362.206 520.5 312.5C520.5 262.794 539.294 148 589 148C638.706 148 752 271.794 752 321.5Z"
|
||||
fill="url(#paint1_linear_1_814)" />
|
||||
</g>
|
||||
<g filter="url(#filter2_f_1_814)">
|
||||
<path
|
||||
d="M694.5 363.5C694.5 407.683 594.183 419 550 419C505.817 419 458 324.182 458 279.999C458 235.817 505.817 211.499 550 211.499C594.183 211.499 694.5 319.317 694.5 363.5Z"
|
||||
fill="url(#paint2_linear_1_814)" />
|
||||
</g>
|
||||
<g filter="url(#filter3_f_1_814)">
|
||||
<path
|
||||
d="M694.5 363.501C694.5 407.684 594.183 419.001 550 419.001C505.817 419.001 458 324.183 458 280C458 235.817 505.817 211.5 550 211.5C594.183 211.5 694.5 319.318 694.5 363.501Z"
|
||||
fill="url(#paint3_linear_1_814)" />
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay">
|
||||
<rect x="516" y="264" width="8" height="72" rx="4" fill="#f3f4f6" />
|
||||
<rect x="536" y="284" width="8" height="32" rx="4" fill="#f3f4f6" />
|
||||
<rect x="556" y="288" width="8" height="24" rx="4" fill="#f3f4f6" />
|
||||
<rect x="576" y="284" width="8" height="32" rx="4" fill="#f3f4f6" />
|
||||
<rect x="596" y="264" width="8" height="72" rx="4" fill="#f3f4f6" />
|
||||
<rect x="616" y="280" width="8" height="40" rx="4" fill="#f3f4f6" />
|
||||
<rect x="636" y="292" width="8" height="16" rx="4" fill="#f3f4f6" />
|
||||
<rect x="656" y="284" width="8" height="32" rx="4" fill="#f3f4f6" />
|
||||
<rect x="676" y="286" width="8" height="28" rx="4" fill="#f3f4f6" />
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_1_814" x="486.23" y="113.73" width="300.04" height="309.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_814" />
|
||||
</filter>
|
||||
<filter id="filter1_f_1_814" x="486.23" y="113.73" width="300.04" height="309.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_814" />
|
||||
</filter>
|
||||
<filter id="filter2_f_1_814" x="423.73" y="177.229" width="305.04" height="276.041" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_814" />
|
||||
</filter>
|
||||
<filter id="filter3_f_1_814" x="423.73" y="177.23" width="305.04" height="276.041" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_814" />
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_814" x1="562.606" y1="180.404" x2="688.231" y2="348"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#6981FF" />
|
||||
<stop offset="1" stop-color="#C68059" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_814" x1="562.606" y1="180.404" x2="688.231" y2="348"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#6981FF" />
|
||||
<stop offset="1" stop-color="#C68059" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_814" x1="550" y1="258.999" x2="550" y2="418.999"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFB6B6" stop-opacity="0.62" />
|
||||
<stop offset="1" stop-color="#6141E1" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_1_814" x1="550" y1="259" x2="550" y2="419" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFB6B6" stop-opacity="0.62" />
|
||||
<stop offset="1" stop-color="#6141E1" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.8 KiB |
92
AudioQnA/docker/ui/svelte/src/lib/assets/icons/svg/5.svg
Normal file
@@ -0,0 +1,92 @@
|
||||
<svg viewBox="0 0 1200 600" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect fill="#f3f4f6" />
|
||||
<g filter="url(#filter0_f_1_751)">
|
||||
<path
|
||||
d="M650.749 324C650.749 373.705 551.706 416.5 502 416.5C452.294 416.5 449.5 303.706 449.5 254C449.5 204.294 490.043 195 539.749 195C589.454 195 650.749 274.294 650.749 324Z"
|
||||
fill="url(#paint0_linear_1_751)" />
|
||||
<path
|
||||
d="M650.749 324C650.749 373.705 551.706 416.5 502 416.5C452.294 416.5 449.5 303.706 449.5 254C449.5 204.294 490.043 195 539.749 195C589.454 195 650.749 274.294 650.749 324Z"
|
||||
fill="url(#paint1_linear_1_751)" />
|
||||
</g>
|
||||
<g filter="url(#filter1_f_1_751)">
|
||||
<path
|
||||
d="M650.749 324C650.749 373.706 551.706 416.501 502 416.501C452.294 416.501 449.5 303.706 449.5 254.001C449.5 204.295 490.043 195 539.749 195C589.454 195 650.749 274.294 650.749 324Z"
|
||||
fill="url(#paint2_linear_1_751)" />
|
||||
<path
|
||||
d="M650.749 324C650.749 373.706 551.706 416.501 502 416.501C452.294 416.501 449.5 303.706 449.5 254.001C449.5 204.295 490.043 195 539.749 195C589.454 195 650.749 274.294 650.749 324Z"
|
||||
fill="url(#paint3_linear_1_751)" />
|
||||
</g>
|
||||
<g filter="url(#filter2_f_1_751)">
|
||||
<path
|
||||
d="M776 296C776 340.183 713.683 408 669.5 408C625.317 408 540 333.183 540 289C540 244.817 573.817 147.5 618 147.5C662.183 147.5 776 251.817 776 296Z"
|
||||
fill="url(#paint4_linear_1_751)" />
|
||||
</g>
|
||||
<g filter="url(#filter3_f_1_751)">
|
||||
<path
|
||||
d="M776 296C776 340.183 713.683 408 669.5 408C625.317 408 540 333.183 540 289C540 244.817 573.817 147.5 618 147.5C662.183 147.5 776 251.817 776 296Z"
|
||||
fill="url(#paint5_linear_1_751)" />
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay">
|
||||
<rect x="516" y="288" width="8" height="24" rx="4" fill="#f3f4f6" />
|
||||
<rect x="536" y="276" width="8" height="48" rx="4" fill="#f3f4f6" />
|
||||
<rect x="556" y="292" width="8" height="16" rx="4" fill="#f3f4f6" />
|
||||
<rect x="576" y="296" width="8" height="8" rx="4" fill="#f3f4f6" />
|
||||
<rect x="596" y="266" width="8" height="68" rx="4" fill="#f3f4f6" />
|
||||
<rect x="616" y="276" width="8" height="48" rx="4" fill="#f3f4f6" />
|
||||
<rect x="636" y="290" width="8" height="20" rx="4" fill="#f3f4f6" />
|
||||
<rect x="656" y="288" width="8" height="24" rx="4" fill="#f3f4f6" />
|
||||
<rect x="676" y="274" width="8" height="52" rx="4" fill="#f3f4f6" />
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_f_1_751" x="415.23" y="160.73" width="269.789" height="290.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_751" />
|
||||
</filter>
|
||||
<filter id="filter1_f_1_751" x="415.23" y="160.73" width="269.789" height="290.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_751" />
|
||||
</filter>
|
||||
<filter id="filter2_f_1_751" x="505.73" y="113.23" width="304.54" height="329.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_751" />
|
||||
</filter>
|
||||
<filter id="filter3_f_1_751" x="505.73" y="113.23" width="304.54" height="329.04" filterUnits="userSpaceOnUse"
|
||||
color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix" />
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
|
||||
<feGaussianBlur stdDeviation="17.135" result="effect1_foregroundBlur_1_751" />
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_1_751" x1="492.606" y1="230.403" x2="618.231" y2="397.999"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF2E00" />
|
||||
<stop offset="1" stop-color="#1400FF" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_1_751" x1="564" y1="218" x2="564" y2="398" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.29" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint2_linear_1_751" x1="492.606" y1="230.404" x2="618.231" y2="398"
|
||||
gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FF2E00" />
|
||||
<stop offset="1" stop-color="#1400FF" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint3_linear_1_751" x1="564" y1="218" x2="564" y2="398" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.29" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint4_linear_1_751" x1="620" y1="209" x2="620" y2="369" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.29" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint5_linear_1_751" x1="620" y1="209" x2="620" y2="369" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00FFA3" stop-opacity="0.29" />
|
||||
<stop offset="1" stop-color="#3300FF" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.8 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg width="37" height="34" viewBox="0 0 37 34" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.102 1.72774e-08C10.9394 -2.8187e-05 10.7784 0.0351312 10.6282 0.103468C10.478 0.171804 10.3415 0.271979 10.2265 0.398272C10.1115 0.524566 10.0204 0.674504 9.95814 0.839519C9.89593 1.00453 9.86393 1.1814 9.86395 1.36V32.64C9.86395 33.0007 9.99439 33.3466 10.2266 33.6017C10.4588 33.8567 10.7737 34 11.102 34C11.4304 34 11.7453 33.8567 11.9775 33.6017C12.2097 33.3466 12.3401 33.0007 12.3401 32.64V1.36C12.3401 1.18139 12.3081 1.00453 12.2459 0.839516C12.1837 0.674501 12.0925 0.524566 11.9776 0.398272C11.8626 0.271979 11.7261 0.171802 11.5759 0.103466C11.4256 0.0351298 11.2646 -2.84533e-05 11.102 1.72774e-08ZM5.69624 6.23677C5.84647 6.16875 6.00747 6.13376 6.17007 6.13379C6.33266 6.13376 6.49367 6.16875 6.6439 6.23677C6.79412 6.30478 6.93061 6.40449 7.04559 6.53019C7.16056 6.65589 7.25175 6.80513 7.31396 6.96937C7.37617 7.13361 7.40818 7.30964 7.40816 7.48741V26.5135C7.40816 26.8725 7.27771 27.2168 7.04553 27.4707C6.81334 27.7245 6.49843 27.8671 6.17007 27.8671C5.84171 27.8671 5.5268 27.7245 5.29461 27.4707C5.06242 27.2168 4.93198 26.8725 4.93198 26.5135V7.48741C4.93196 7.30965 4.96396 7.13361 5.02617 6.96937C5.08838 6.80513 5.17958 6.6559 5.29455 6.53019C5.40952 6.40449 5.54602 6.30479 5.69624 6.23677ZM0.764261 11.4362C0.914484 11.3683 1.07549 11.3334 1.23809 11.3334C1.40068 11.3334 1.56169 11.3683 1.71191 11.4362C1.86213 11.5041 1.99863 11.6036 2.1136 11.7291C2.22857 11.8545 2.31977 12.0034 2.38198 12.1674C2.44419 12.3313 2.4762 12.507 2.47617 12.6844V21.3158C2.47617 21.4932 2.44415 21.6689 2.38193 21.8328C2.31971 21.9967 2.22851 22.1456 2.11355 22.2711C1.99858 22.3965 1.86209 22.496 1.71188 22.5639C1.56167 22.6318 1.40067 22.6668 1.23809 22.6668C1.0755 22.6668 0.914503 22.6318 0.764292 22.5639C0.61408 22.496 0.477595 22.3965 0.362628 22.2711C0.247661 22.1456 0.156464 21.9967 0.0942445 21.8328C0.0320249 21.6689 1.57287e-08 21.4932 1.57287e-08 21.3158V12.6844C-2.59027e-05 12.507 0.0319806 12.3313 0.094191 12.1674C0.156402 12.0035 0.247598 11.8545 0.36257 11.7291C0.477542 11.6036 0.614037 11.5041 0.764261 11.4362ZM15.5602 6.23677C15.7104 6.16875 15.8714 6.13376 16.034 6.13379C16.1966 6.13376 16.3576 6.16875 16.5078 6.23677C16.6581 6.30478 16.7945 6.40449 16.9095 6.53019C17.0245 6.65589 17.1157 6.80513 17.1779 6.96937C17.2401 7.13361 17.2721 7.30964 17.2721 7.48741V26.5135C17.2721 26.8725 17.1417 27.2168 16.9095 27.4707C16.6773 27.7245 16.3624 27.8671 16.034 27.8671C15.7056 27.8671 15.3907 27.7245 15.1585 27.4707C14.9264 27.2168 14.7959 26.8725 14.7959 26.5135V7.48741C14.7959 7.30965 14.8279 7.13361 14.8901 6.96937C14.9523 6.80513 15.0435 6.65589 15.1585 6.53019C15.2735 6.40449 15.41 6.30479 15.5602 6.23677ZM20.966 11.3334C20.8034 11.3334 20.6424 11.3683 20.4922 11.4362C20.3419 11.5041 20.2054 11.6036 20.0905 11.7291C19.9755 11.8545 19.8843 12.0035 19.8221 12.1674C19.7599 12.3313 19.7279 12.507 19.7279 12.6844V21.3158C19.7279 21.6741 19.8583 22.0177 20.0905 22.2711C20.3227 22.5244 20.6376 22.6668 20.966 22.6668C21.2943 22.6668 21.6093 22.5244 21.8414 22.2711C22.0736 22.0177 22.2041 21.6741 22.2041 21.3158V12.6844C22.2041 12.507 22.1721 12.3313 22.1099 12.1674C22.0477 12.0034 21.9565 11.8545 21.8415 11.7291C21.7265 11.6036 21.59 11.5041 21.4398 11.4362C21.2896 11.3683 21.1286 11.3334 20.966 11.3334ZM25.4241 6.23677C25.5744 6.16875 25.7354 6.13376 25.898 6.13379C26.0606 6.13376 26.2216 6.16875 26.3718 6.23677C26.522 6.30479 26.6585 6.40449 26.7735 6.53019C26.8885 6.65589 26.9796 6.80513 27.0419 6.96937C27.1041 7.13361 27.1361 7.30964 27.136 7.48741V26.5135C27.136 26.8725 27.0056 27.2168 26.7734 27.4707C26.5412 27.7245 26.2263 27.8671 25.898 27.8671C25.5696 27.8671 25.2547 27.7245 25.0225 27.4707C24.7903 27.2168 24.6599 26.8725 24.6599 26.5135V7.48741C24.6598 7.30965 24.6919 7.13361 24.7541 6.96937C24.8163 6.80513 24.9075 6.65589 25.0224 6.53019C25.1374 6.40449 25.2739 6.30479 25.4241 6.23677ZM30.8299 11.3334C30.6674 11.3334 30.5063 11.3683 30.3561 11.4362C30.2059 11.5041 30.0694 11.6036 29.9544 11.7291C29.8395 11.8545 29.7483 12.0035 29.686 12.1674C29.6238 12.3313 29.5918 12.507 29.5919 12.6844V21.3158C29.5919 21.6741 29.7223 22.0177 29.9545 22.2711C30.1867 22.5244 30.5016 22.6668 30.8299 22.6668C31.1583 22.6668 31.4732 22.5244 31.7054 22.2711C31.9376 22.0177 32.068 21.6741 32.068 21.3158V12.6844C32.0681 12.507 32.036 12.3313 31.9738 12.1674C31.9116 12.0034 31.8204 11.8545 31.7055 11.7291C31.5905 11.6036 31.454 11.5041 31.3038 11.4362C31.1535 11.3683 30.9925 11.3334 30.8299 11.3334ZM35.7619 15.6003C35.0781 15.6003 34.5238 16.1546 34.5238 16.8384V17.0289C34.5238 17.7126 35.0781 18.2669 35.7619 18.2669C36.4457 18.2669 37 17.7126 37 17.0289V16.8384C37 16.1546 36.4457 15.6003 35.7619 15.6003Z" fill="#538DFF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg t="1688623790304" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3103"
|
||||
width="200" height="200">
|
||||
<path
|
||||
d="M512 1024a512 512 0 1 1 512-512 512 512 0 0 1-512 512z m0-896a384 384 0 1 0 384 384A384 384 0 0 0 512 128z m128 576h-256a64 64 0 0 1-64-64v-256a64 64 0 0 1 64-64h256a64 64 0 0 1 64 64v256a64 64 0 0 1-64 64z"
|
||||
fill="#d81e06" p-id="3104"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 429 B |
@@ -0,0 +1 @@
|
||||
<svg t="1713431562066" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6399" width="32" height="32"><path d="M592 768h-160c-26.6 0-48-21.4-48-48V384h-175.4c-35.6 0-53.4-43-28.2-68.2L484.6 11.4c15-15 39.6-15 54.6 0l304.4 304.4c25.2 25.2 7.4 68.2-28.2 68.2H640v336c0 26.6-21.4 48-48 48z m432-16v224c0 26.6-21.4 48-48 48H48c-26.6 0-48-21.4-48-48V752c0-26.6 21.4-48 48-48h272v16c0 61.8 50.2 112 112 112h160c61.8 0 112-50.2 112-112v-16h272c26.6 0 48 21.4 48 48z m-248 176c0-22-18-40-40-40s-40 18-40 40 18 40 40 40 40-18 40-40z m128 0c0-22-18-40-40-40s-40 18-40 40 18 40 40 40 40-18 40-40z" p-id="6400" fill="#ffffff"></path></svg>
|
||||
|
After Width: | Height: | Size: 669 B |
@@ -0,0 +1,9 @@
|
||||
<svg t="1688438032617" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2960"
|
||||
width="200" height="200">
|
||||
<path
|
||||
d="M512 705.728c105.888 0 192-86.112 192-192L704 257.952c0-105.888-86.112-192-192-192s-192 86.112-192 192l0 255.776C320 619.584 406.112 705.728 512 705.728z"
|
||||
fill="#707070" p-id="2961"></path>
|
||||
<path
|
||||
d="M864 479.776 864 352c0-17.664-14.304-32-32-32s-32 14.336-32 32l0 127.776c0 160.16-129.184 290.464-288 290.464-158.784 0-288-130.304-288-290.464L224 352c0-17.664-14.336-32-32-32s-32 14.336-32 32l0 127.776c0 184.608 140.864 336.48 320 352.832L480 896 288 896c-17.664 0-32 14.304-32 32s14.336 32 32 32l448 0c17.696 0 32-14.304 32-32s-14.304-32-32-32l-192 0 0-63.36C723.136 816.256 864 664.384 864 479.776z"
|
||||
fill="#707070" p-id="2962"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 844 B |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 15 KiB |
26
AudioQnA/docker/ui/svelte/src/lib/common/sse.d.ts
vendored
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.
|
||||
|
||||
declare module "sse.js" {
|
||||
export type SSEOptions = EventSourceInit & {
|
||||
headers?: Record<string, string>;
|
||||
payload?: string;
|
||||
method?: string;
|
||||
};
|
||||
|
||||
export class SSE extends EventSource {
|
||||
constructor(url: string | URL, sseOptions?: SSEOptions);
|
||||
stream(): void;
|
||||
}
|
||||
}
|
||||
37
AudioQnA/docker/ui/svelte/src/lib/common/timediff.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
// 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 default function timeDifference(current: number, previous: number) {
|
||||
const msPerMinute = 60 * 1000;
|
||||
const msPerHour = msPerMinute * 60;
|
||||
const msPerDay = msPerHour * 24;
|
||||
const msPerMonth = msPerDay * 30;
|
||||
const msPerYear = msPerDay * 365;
|
||||
|
||||
const elapsed = current - previous;
|
||||
|
||||
if (elapsed < msPerMinute) {
|
||||
return Math.round(elapsed / 1000) + " seconds ago";
|
||||
} else if (elapsed < msPerHour) {
|
||||
return Math.round(elapsed / msPerMinute) + " minutes ago";
|
||||
} else if (elapsed < msPerDay) {
|
||||
return Math.round(elapsed / msPerHour) + " hours ago";
|
||||
} else if (elapsed < msPerMonth) {
|
||||
return "approximately " + Math.round(elapsed / msPerDay) + " days ago";
|
||||
} else if (elapsed < msPerYear) {
|
||||
return "approximately " + Math.round(elapsed / msPerMonth) + " months ago";
|
||||
} else {
|
||||
return "approximately " + Math.round(elapsed / msPerYear) + " years ago";
|
||||
}
|
||||
}
|
||||