Commit
·
c976bfb
1
Parent(s):
9261e02
first commit
Browse files- .DS_Store +0 -0
- Dockerfile +24 -0
- HOME.py +36 -0
- LICENSE +21 -0
- README.md +7 -6
- assets/credential/ambient-hulling-389607-89c372b7af63.json +13 -0
- assets/images/logo.png +0 -0
- functions/.DS_Store +0 -0
- functions/SK/.DS_Store +0 -0
- functions/SK/TCDKPlanner.py +36 -0
- functions/SK/__init__.py +0 -0
- functions/SK/__pycache__/TCDKPlanner.cpython-311.pyc +0 -0
- functions/SK/__pycache__/__init__.cpython-311.pyc +0 -0
- functions/SK/plugins/.DS_Store +0 -0
- functions/SK/plugins/Planner/GetIntent/config.json +21 -0
- functions/SK/plugins/Planner/GetIntent/skprompt.txt +43 -0
- functions/SK/plugins/Planner/planner_prompt.txt +48 -0
- functions/SK/plugins/QdrantSkill/CreateResponse/config.json +26 -0
- functions/SK/plugins/QdrantSkill/CreateResponse/skprompt.txt +10 -0
- functions/SK/plugins/QdrantSkill/QdrantQuery.py +41 -0
- functions/SK/plugins/QdrantSkill/QdrantSkill.py +57 -0
- functions/SK/plugins/QdrantSkill/__pycache__/QdrantQuery.cpython-311.pyc +0 -0
- functions/SK/plugins/QdrantSkill/__pycache__/QdrantQuery2.cpython-311.pyc +0 -0
- functions/SK/plugins/QdrantSkill/__pycache__/QdrantSkill.cpython-311.pyc +0 -0
- functions/SK/plugins/QdrantSkill/__pycache__/QdrantSkillPlanner.cpython-311.pyc +0 -0
- functions/SK/plugins/SQLskill/CreateResponse/config.json +26 -0
- functions/SK/plugins/SQLskill/CreateResponse/skprompt.txt +15 -0
- functions/SK/plugins/SQLskill/CreateSQLQuery/config.json +26 -0
- functions/SK/plugins/SQLskill/CreateSQLQuery/skprompt.txt +51 -0
- functions/SK/plugins/SQLskill/SQLFunctions.py +48 -0
- functions/SK/plugins/SQLskill/SQLskill.py +47 -0
- functions/SK/plugins/SQLskill/__pycache__/SQLFunctions.cpython-311.pyc +0 -0
- functions/SK/plugins/SQLskill/__pycache__/SQLskill.cpython-311.pyc +0 -0
- functions/__init__.py +0 -0
- functions/__pycache__/__init__.cpython-311.pyc +0 -0
- functions/__pycache__/csdl_tcdk.cpython-311.pyc +0 -0
- pages/01_CSDL TCDK.py +37 -0
- pages/__init__.py +0 -0
- requirements.txt +8 -0
- style/style.css +70 -0
- ui/__init__.py +1 -0
- ui/__pycache__/__init__.cpython-311.pyc +0 -0
- ui/__pycache__/ui_csdltcdk.cpython-311.pyc +0 -0
- ui/ui_csdltcdk.py +76 -0
.DS_Store
ADDED
|
Binary file (8.2 kB). View file
|
|
|
Dockerfile
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
FROM python:3.10
|
| 2 |
+
|
| 3 |
+
WORKDIR /app
|
| 4 |
+
COPY . /app/
|
| 5 |
+
RUN pip install --upgrade pip
|
| 6 |
+
RUN pip install --no-cache-dir --upgrade -r /app/requirements.txt
|
| 7 |
+
|
| 8 |
+
RUN apt-get update
|
| 9 |
+
RUN apt-get install -y tdsodbc unixodbc-dev
|
| 10 |
+
RUN apt install unixodbc -y
|
| 11 |
+
RUN apt-get clean -y
|
| 12 |
+
# DEPENDECES FOR DOWNLOAD ODBC DRIVER
|
| 13 |
+
RUN apt-get install apt-transport-https
|
| 14 |
+
RUN curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
|
| 15 |
+
RUN curl https://packages.microsoft.com/config/debian/10/prod.list > /etc/apt/sources.list.d/mssql-release.list
|
| 16 |
+
RUN apt-get update
|
| 17 |
+
# INSTALL ODBC DRIVER
|
| 18 |
+
RUN ACCEPT_EULA=Y apt-get install msodbcsql17 --assume-yes
|
| 19 |
+
# CONFIGURE ENV FOR /bin/bash TO USE MSODBCSQL17
|
| 20 |
+
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bash_profile
|
| 21 |
+
RUN echo 'export PATH="$PATH:/opt/mssql-tools/bin"' >> ~/.bashrc
|
| 22 |
+
|
| 23 |
+
ENTRYPOINT [ "streamlit" , "run"]
|
| 24 |
+
CMD ["/app/HOME.py", "--server.address", "0.0.0.0", "--server.port", "7860", "tuananguyen-TCDK.hf.space"]
|
HOME.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
from ui import *
|
| 3 |
+
from functions import *
|
| 4 |
+
from PIL import Image
|
| 5 |
+
from dotenv import load_dotenv
|
| 6 |
+
|
| 7 |
+
logo = Image.open("./assets/images/logo.png")
|
| 8 |
+
st.set_page_config(# Alternate names: setup_page, page, layout
|
| 9 |
+
layout="wide", # Can be "centered" or "wide". In the future also "dashboard", etc.
|
| 10 |
+
initial_sidebar_state="auto", # Can be "auto", "expanded", "collapsed"
|
| 11 |
+
page_title="CSDL TCDK", # String or None. Strings get appended with "• Streamlit".
|
| 12 |
+
page_icon=logo, # String, anything supported by st.image, or None.
|
| 13 |
+
)
|
| 14 |
+
# Add logo to sidebar
|
| 15 |
+
# add_logo()
|
| 16 |
+
|
| 17 |
+
# --- LOAD CSS ------------------------------------------------------------------
|
| 18 |
+
with open("./style/style.css") as f:
|
| 19 |
+
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
|
| 20 |
+
|
| 21 |
+
# --- LOAD .ENV -----------------------------------------------------------------
|
| 22 |
+
# Load environment variables from .env file
|
| 23 |
+
load_dotenv()
|
| 24 |
+
|
| 25 |
+
# --- GIOI THIEU ----------------------------------------------------------------
|
| 26 |
+
content = """
|
| 27 |
+
### Công cụ hỏi đáp với Cơ sở dữ liệu bài báo Tạp chí Dầu khí
|
| 28 |
+
Công cụ hỏi đáp với Cơ sở dữ liệu bài báo Tạp chí Dầu khí là một ứng dụng mạnh mẽ và tiện lợi giúp bạn tra cứu thông tin về các bài báo, tác giả, tóm tắt và nhiều tính năng khác liên quan đến lĩnh vực dầu khí. Với sự kết hợp giữa cơ sở dữ liệu phong phú và tính năng hỏi đáp thông minh, công cụ này sẽ giúp bạn dễ dàng tìm kiếm và tiếp cận kiến thức chuyên ngành một cách nhanh chóng.
|
| 29 |
+
#### Tính năng chính:
|
| 30 |
+
1. **Tra cứu bài báo**: Bạn có thể tìm kiếm bất kỳ bài báo nào trong cơ sở dữ liệu của Tạp chí Dầu khí dựa trên tiêu đề, tác giả, hoặc từ khóa liên quan.
|
| 31 |
+
2. **Tra cứu tác giả**: Công cụ cho phép bạn xem thông tin chi tiết về các tác giả, bao gồm danh sách các bài báo họ đã viết.
|
| 32 |
+
3. **Tóm tắt bài báo**: Bạn có thể đọc tóm tắt ngắn gọn của các bài báo để nắm bắt nội dung chính một cách nhanh chóng.
|
| 33 |
+
4. **Hỏi đáp với nội dung bài báo**: Tính năng này cho phép bạn đặt câu hỏi và nhận được câu trả lời dựa trên nội dung của các bài báo trong cơ sở dữ liệu. Điều này giúp bạn giải quyết các vấn đề và thắc mắc liên quan đến dầu khí một cách hiệu quả.
|
| 34 |
+
Với công cụ hỏi đáp này, bạn sẽ có trải nghiệm nhanh chóng và tiện lợi khi tìm hiểu về lĩnh vực quan trọng của dầu khí. Hãy khám phá ngay để nâng cao kiến thức và năng lực của bạn trong lĩnh vực này.
|
| 35 |
+
"""
|
| 36 |
+
st.markdown(content)
|
LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2023 tuan.a.nguyen
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
-
sdk:
|
| 7 |
pinned: false
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
| 1 |
---
|
| 2 |
+
title: TCDK
|
| 3 |
+
emoji: 🐨
|
| 4 |
+
colorFrom: pink
|
| 5 |
+
colorTo: yellow
|
| 6 |
+
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
+
license: apache-2.0
|
| 9 |
---
|
| 10 |
|
| 11 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
assets/credential/ambient-hulling-389607-89c372b7af63.json
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"type": "service_account",
|
| 3 |
+
"project_id": "ambient-hulling-389607",
|
| 4 |
+
"private_key_id": "89c372b7af63009ccf01bca809249747251805bc",
|
| 5 |
+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCYBcIUHlULNHU8\ngr+vtBa1lsvuIRcjdS+sqzAqWJcmTY3j4oad/AkCeGPikCWhX5cfq8z7KBBaNu31\naYztMajumwnvJKte2h0c5c2rnzMJ3tx6JyMoPZsT58ja4GGgwlCKSR5W/LGn3mCp\nAxd8rGBWIxEwT5ASthul9KI9mSzulHPcJ8ZtIjd5XYikUKdsSwjjJVUXjWZE4xzi\nKIBYQ2lDpj+83BGUGCJka+7tnvS78VSiS4bWDOPqF6cqc+JsiURu/dLHUlBCTxWR\nohgSCm46acdadleZVTnJsK6zSg8PLHBqhvQwIHQAudQ4kc13NzbVSnb2t4WeRQXs\n57eF02chAgMBAAECggEAEgdiyiiDvPGycqPt8Dw7EjuJQVsux497AS8HJgp+GHaL\nnIpNnThZ6C9XZzPhppbz0Pd6tpF8iPppM5jaM/oW9v8viSsv4K6c08PEJbWaY7II\nszrnfjr6JHzxUtXX9iz9SL0dqkLLHeWvUHPzqd82iJidjf1tkG6E7mRKBmSfUcbe\nAICzxtC400fDb22dmfxuqeunlWsx0URjSmYV8NXSwmfYHDJ72zxOXb1a1Zf2qbiO\n0nAxPgB+yQ0zQgeEqo0X4pkqc3v5UHlPn0Wph3TcM+EPgn3LZ6aPE3ze03iPWNJp\nXTpXMAcWhqKLAZWd8V/rktY1JFUO0AA5CNLTgW6xjQKBgQDG/zvk7PlpyVij7C7L\naVP9Y649NA7R7sCdRefI2v/yt6uxxFpTrSMlfDAsG0QmksCPmUIeWeX1FUXG9k+A\niQYj+rn2kxRc8Ny2PJfEhahqjwqgIo9dydibsXLkhNG3ptYi3iIqOUb7HBN9nvJG\n4/x6KjHJD38nmPr7/0dNHVIWXQKBgQDDkc76IROYXp5xHjzI9kZQEiBTuc15UhGE\nZs6mi6PvORRRzwTIXGQXdjAIY0dr2BL7/fHLSqniPUYiuvJvJNPNMIkHF50GBS8C\n+vq0N3LMkKRu3UfXPGeapJc0jQFJMMuvziFvInmBqelN4CnUhb73kaaobyn3/oT0\ndaW9oAG/lQKBgCY5rxqpfruYZsOOQerm/7BD7ptpHZOsBinv3LdTgijwqTWLn0JF\nluPDeElwr2WtePncmbvUzvyGKpIujFUHfTt6FTDNTfMQfYUwHIMunYxij8r0+I8u\nj8JQkt5cuSBLFwU5oFx2BjGEUiYmWynM75nT8x5JMMa9dzDi96JTiIotAoGBAJJT\nZ0SZOPsZWH0UfbBzK7q/RTa/33A1qmuhLF9KPddAouZu+YocLrurL1cnSQn0uoeW\nwrIzZBald/OGYtwr9tkgxnXrAg6+FCWruabbkeZjFtToddciF/aJzaSBGAQ2IUCh\n/zwS1Ezi32/oGAQuKes8LDD8M6+c3Me3utG9hXFdAoGBAKBmlDfjj4ecpi7v5K/g\nD3eoLu23w3ZLzH2pzGHKugmXkTR2E7Yl4OPH2AqlujaGBrXPQbq2ly3Y+I7PdXEZ\nkjOlLBy7i+x7PH24fOwkmvXCQN7z/xFBcZKqqSnESOPZXptPxOEFuiWNYLzzqjlu\nsXSLfosRsI8h2Sg8i2Il0fWT\n-----END PRIVATE KEY-----\n",
|
| 6 |
+
"client_email": "palm-everywhere@ambient-hulling-389607.iam.gserviceaccount.com",
|
| 7 |
+
"client_id": "115515026441349382697",
|
| 8 |
+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
| 9 |
+
"token_uri": "https://oauth2.googleapis.com/token",
|
| 10 |
+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
| 11 |
+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/palm-everywhere%40ambient-hulling-389607.iam.gserviceaccount.com",
|
| 12 |
+
"universe_domain": "googleapis.com"
|
| 13 |
+
}
|
assets/images/logo.png
ADDED
|
functions/.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
functions/SK/.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
functions/SK/TCDKPlanner.py
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from semantic_kernel.kernel import Kernel
|
| 3 |
+
from semantic_kernel.planning.basic_planner import BasicPlanner
|
| 4 |
+
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
|
| 5 |
+
from semantic_kernel.utils.settings import openai_settings_from_dot_env
|
| 6 |
+
|
| 7 |
+
from .plugins.SQLskill.SQLskill import SQLskill
|
| 8 |
+
from .plugins.QdrantSkill.QdrantSkill import QdrantSkillPlan
|
| 9 |
+
from dotenv import load_dotenv
|
| 10 |
+
|
| 11 |
+
# Load environment variables from .env file
|
| 12 |
+
load_dotenv()
|
| 13 |
+
|
| 14 |
+
async def main_tcdk(query):
|
| 15 |
+
# Instantiate your kernel
|
| 16 |
+
kernel = Kernel()
|
| 17 |
+
|
| 18 |
+
# Configure AI service used by the kernel. Load settings from the .env file.
|
| 19 |
+
api_key, org_id = os.environ['OPENAI_API_KEY'], ""
|
| 20 |
+
|
| 21 |
+
kernel.add_text_completion_service(
|
| 22 |
+
"dv", OpenAIChatCompletion(os.environ['OPENAI_MODEL_NAME'], api_key, org_id)
|
| 23 |
+
)
|
| 24 |
+
# Load file txt to a string variable
|
| 25 |
+
PROMPT = open("functions/SK/plugins/Planner/planner_prompt.txt", "r").read()
|
| 26 |
+
# Import Qdrant Nested Skill
|
| 27 |
+
kernel.import_skill(QdrantSkillPlan(), "QdrantSkill")
|
| 28 |
+
# Import the native functions
|
| 29 |
+
kernel.import_skill(SQLskill(), "SQLskill")
|
| 30 |
+
|
| 31 |
+
planner = BasicPlanner()
|
| 32 |
+
basic_plan = await planner.create_plan_async(query, kernel, prompt=PROMPT)
|
| 33 |
+
generated_plan = basic_plan.generated_plan
|
| 34 |
+
results = await planner.execute_plan_async(basic_plan, kernel)
|
| 35 |
+
|
| 36 |
+
return generated_plan, results
|
functions/SK/__init__.py
ADDED
|
File without changes
|
functions/SK/__pycache__/TCDKPlanner.cpython-311.pyc
ADDED
|
Binary file (2.06 kB). View file
|
|
|
functions/SK/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (162 Bytes). View file
|
|
|
functions/SK/plugins/.DS_Store
ADDED
|
Binary file (6.15 kB). View file
|
|
|
functions/SK/plugins/Planner/GetIntent/config.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema": 1,
|
| 3 |
+
"description": "Classify user input question into a JSON structure including level of difficulity and some sub questions which are more simpler.",
|
| 4 |
+
"type": "completion",
|
| 5 |
+
"completion": {
|
| 6 |
+
"max_tokens": 1000,
|
| 7 |
+
"temperature": 0.0,
|
| 8 |
+
"top_p": 0.0,
|
| 9 |
+
"presence_penalty": 0.6,
|
| 10 |
+
"frequency_penalty": 0.0
|
| 11 |
+
},
|
| 12 |
+
"input": {
|
| 13 |
+
"parameters": [
|
| 14 |
+
{
|
| 15 |
+
"name": "input",
|
| 16 |
+
"description": "The user's request.",
|
| 17 |
+
"defaultValue": ""
|
| 18 |
+
}
|
| 19 |
+
]
|
| 20 |
+
}
|
| 21 |
+
}
|
functions/SK/plugins/Planner/GetIntent/skprompt.txt
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Phân loại chủ đề và viết lại câu hỏi
|
| 2 |
+
Phân tích và đánh giá mức độ phức tạp của câu hỏi, sau đó phân loại vào một trong hai loại (đơn giản hoặc phức tạp)
|
| 3 |
+
- Đơn giản (simple): câu hỏi chỉ chứa một chủ đề, chủ thể, không có từ khóa phủ định, không có từ khóa so sánh, hỏi về các khái niệm
|
| 4 |
+
- Phức tạp (complicated): câu hỏi chứa nhiều chủ đề, chủ thể, có từ khóa phủ định, có từ khóa so sánh, phân tích, có nguyên nhân kết quả
|
| 5 |
+
|
| 6 |
+
Viết lại câu hỏi theo phong cách đơn giản, trực tiếp, đầy đủ cấu trúc chủ ngữ vị ngữ
|
| 7 |
+
Với câu hỏi phức tạp, hãy viết lại thành nhiều câu hỏi đơn giản bao hàm từng phần của câu hỏi phức tạp
|
| 8 |
+
|
| 9 |
+
KẾT QUẢ TRẢ VỀ TUÂN THỦ CÁC NGUYÊN TẮC SAU:
|
| 10 |
+
- KẾT QUẢ TRẢ THEO CẤU TRÚC JSON VỚI 2 TRƯỜNG "level" và "question".
|
| 11 |
+
Trong đó "level" chỉ là 1 trong 2 giá trị "simple" hoặc "complicated", "question" là câu hỏi đã được viết lại.
|
| 12 |
+
Nếu có nhiều câu hỏi viết lại, hãy giữ đúng cấu trúc JSON
|
| 13 |
+
- KHÔNG BAO GỒM CÁC THÔNG TIN KHÁC
|
| 14 |
+
|
| 15 |
+
[Input]
|
| 16 |
+
Có bao nhiêu tác giả thuộc Viện Dầu khí Việt Nam?
|
| 17 |
+
[Output]
|
| 18 |
+
{
|
| 19 |
+
"level": "simple",
|
| 20 |
+
"question": "Có bao nhiêu tác giả thuộc Viện Dầu khí Việt Nam?",
|
| 21 |
+
}
|
| 22 |
+
[Input]
|
| 23 |
+
Địa chấn phản xạ là gì?
|
| 24 |
+
[Output]
|
| 25 |
+
{
|
| 26 |
+
"level": "simple",
|
| 27 |
+
"question": "Địa chấn phản xạ là gì?",
|
| 28 |
+
}
|
| 29 |
+
[Input]
|
| 30 |
+
So sánh số lượng bài báo của tác giả Trương Văn Nhân và Hoàng Long?
|
| 31 |
+
[Output]
|
| 32 |
+
{
|
| 33 |
+
"level": "complicated",
|
| 34 |
+
"question": {
|
| 35 |
+
"q1": "Tác giả Trương Văn Nhân có bao nhiêu bài báo?",
|
| 36 |
+
"q2": "Tác giả Hoàng Long có bao nhiêu bài báo?"
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
+++++
|
| 41 |
+
[Input]
|
| 42 |
+
{{$input}}
|
| 43 |
+
[Output]
|
functions/SK/plugins/Planner/planner_prompt.txt
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
You are a planner for the Semantic Kernel.
|
| 2 |
+
Your job is to create a properly formatted JSON plan step by step, to satisfy the goal given.
|
| 3 |
+
Create a JSON of subtask based off the [GOAL] provided. JSON needs only 01 subtask.
|
| 4 |
+
Subtask must be from within the [AVAILABLE FUNCTIONS] list. Do not use any functions that are not in the list.
|
| 5 |
+
Based on the [GOAL], you need to decide which function to use and what arguments to provide.
|
| 6 |
+
There are 2 types of functions: QdrantSkill.qdrant_request and SQLskill.sql_request.
|
| 7 |
+
"QdrantSkill.qdrant_request" is used to answer summarization or definition question.
|
| 8 |
+
"SQLskill.sql_request" is used to answer detail, analystics question which required information in a SQL database.
|
| 9 |
+
Question Classification Example:
|
| 10 |
+
"Phương pháp xử lý tín hiệu phi tuyến là gì?" -> This is a summarization question, so you need to use QdrantSkill.qdrant_request
|
| 11 |
+
"Bể Cửu Long có đặc điểm địa chất chung là gì?" -> This is a summarization question, so you need to use QdrantSkill.qdrant_request
|
| 12 |
+
"Tra cứu thông tin tác giả bài báo PVJ2022.01.02" -> This is a detail question, so you need to use SQLskill.sql_request
|
| 13 |
+
"Có bao nhiêu bài báo về lĩnh vực Hoá chế biến" -> This is a detail question, so you need to use SQLskill.sql_request
|
| 14 |
+
Base your decisions on which functions to use from the description and the name of the function.
|
| 15 |
+
Sometimes, a function may take arguments. Provide them if necessary.
|
| 16 |
+
The plan should be as short as possible.
|
| 17 |
+
For example:
|
| 18 |
+
|
| 19 |
+
[AVAILABLE FUNCTIONS]
|
| 20 |
+
QdrantSkill.qdrant_request
|
| 21 |
+
description: Answer question about energy market using market daily reports saved in Qdrant
|
| 22 |
+
args:
|
| 23 |
+
- input: The raw question for querying
|
| 24 |
+
|
| 25 |
+
SQLskill.sql_request
|
| 26 |
+
description: Answer a question which is required to query data from SQL database
|
| 27 |
+
args:
|
| 28 |
+
- input: The raw question related to SQL database
|
| 29 |
+
|
| 30 |
+
[GOAL]
|
| 31 |
+
"Phương pháp xử lý tín hiệu phi tuyến là gì và ứng dụng của nó là gì?"
|
| 32 |
+
|
| 33 |
+
[OUTPUT]
|
| 34 |
+
{
|
| 35 |
+
"input": "Phương pháp xử lý tín hiệu phi tuyến là gì và ứng dụng của nó là gì?",
|
| 36 |
+
"subtasks": [
|
| 37 |
+
{"function": "QdrantSkill.qdrant_request", "args": {"input": "Phương pháp xử lý tín hiệu phi tuyến là gì và ứng dụng của nó là gì?"}}
|
| 38 |
+
]
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
[AVAILABLE FUNCTIONS]
|
| 43 |
+
{{$available_functions}}
|
| 44 |
+
|
| 45 |
+
[GOAL]
|
| 46 |
+
{{$goal}}
|
| 47 |
+
|
| 48 |
+
[OUTPUT]
|
functions/SK/plugins/QdrantSkill/CreateResponse/config.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema": 1,
|
| 3 |
+
"type": "completion",
|
| 4 |
+
"description": "Creates a final response based on the original request and addition information during the pipeline",
|
| 5 |
+
"completion": {
|
| 6 |
+
"max_tokens": 2000,
|
| 7 |
+
"temperature": 0.0,
|
| 8 |
+
"top_p": 0.0,
|
| 9 |
+
"presence_penalty": 0.0,
|
| 10 |
+
"frequency_penalty": 0.0
|
| 11 |
+
},
|
| 12 |
+
"input": {
|
| 13 |
+
"parameters": [
|
| 14 |
+
{
|
| 15 |
+
"name": "input",
|
| 16 |
+
"description": "The addition information that recieved from Qdrant Database.",
|
| 17 |
+
"defaultValue": ""
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"name": "original_request",
|
| 21 |
+
"description": "The original request from the user.",
|
| 22 |
+
"defaultValue": ""
|
| 23 |
+
}
|
| 24 |
+
]
|
| 25 |
+
}
|
| 26 |
+
}
|
functions/SK/plugins/QdrantSkill/CreateResponse/skprompt.txt
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
You will be provided with the question which is delimited by XML tags and
|
| 2 |
+
the context delimited by triple backticks.
|
| 3 |
+
The context contains some long paragraphs and references which delimited by triple dash.
|
| 4 |
+
GIVE THE ANSWER IN VIETNAMESE
|
| 5 |
+
|
| 6 |
+
<tag>{{$original_request}} </tag>\n
|
| 7 |
+
|
| 8 |
+
```
|
| 9 |
+
{{$input}}
|
| 10 |
+
```
|
functions/SK/plugins/QdrantSkill/QdrantQuery.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os, openai, json
|
| 2 |
+
from qdrant_client import QdrantClient
|
| 3 |
+
from semantic_kernel import Kernel
|
| 4 |
+
from semantic_kernel.skill_definition import (
|
| 5 |
+
sk_function,
|
| 6 |
+
sk_function_context_parameter,
|
| 7 |
+
)
|
| 8 |
+
from semantic_kernel.orchestration.sk_context import SKContext
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
class QdrantQueryClass:
|
| 12 |
+
def __init__(self, kernel: Kernel):
|
| 13 |
+
self._kernel = kernel
|
| 14 |
+
@sk_function(
|
| 15 |
+
description="Ask Qdrant Vector database to receive some added information.",
|
| 16 |
+
name="contextQueryPlan",
|
| 17 |
+
)
|
| 18 |
+
# @sk_function_context_parameter(name="original_request", description="The raw question for querying")
|
| 19 |
+
# @sk_function_context_parameter(name="input", description="The raw question for querying")
|
| 20 |
+
def context_query(self, context: SKContext) -> str:
|
| 21 |
+
qdrant_client = QdrantClient(url=os.environ['QDRANT_URL'], api_key=os.environ['QDRANT_API_KEY'])
|
| 22 |
+
|
| 23 |
+
openai.api_key = os.environ['OPENAI_API_KEY']
|
| 24 |
+
|
| 25 |
+
query_vector = openai.Embedding.create(
|
| 26 |
+
input = context["input"],
|
| 27 |
+
model="text-embedding-ada-002",
|
| 28 |
+
)['data'][0]['embedding']
|
| 29 |
+
results = qdrant_client.search(collection_name=os.environ['COLLECTION_NAME'],
|
| 30 |
+
query_vector=query_vector,
|
| 31 |
+
limit=5,
|
| 32 |
+
)
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
#Return all results
|
| 36 |
+
context['context_results'] = results
|
| 37 |
+
#Return
|
| 38 |
+
matched_ans = ''
|
| 39 |
+
for i in range(len(results)):
|
| 40 |
+
matched_ans += '\n---\n' + str(json.loads(results[0].payload['_node_content'])['text'].replace('\n', ' '))
|
| 41 |
+
return matched_ans
|
functions/SK/plugins/QdrantSkill/QdrantSkill.py
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from semantic_kernel import Kernel
|
| 3 |
+
from semantic_kernel.orchestration.sk_context import SKContext
|
| 4 |
+
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
|
| 5 |
+
from semantic_kernel.utils.settings import openai_settings_from_dot_env
|
| 6 |
+
from semantic_kernel.skill_definition import sk_function, sk_function_context_parameter
|
| 7 |
+
|
| 8 |
+
from .QdrantQuery import QdrantQueryClass
|
| 9 |
+
|
| 10 |
+
class QdrantSkillPlan:
|
| 11 |
+
def __init__(self):
|
| 12 |
+
self.subKernel = Kernel()
|
| 13 |
+
api_key, org_id = os.environ['OPENAI_API_KEY'], ""
|
| 14 |
+
|
| 15 |
+
self.subKernel.add_text_completion_service(
|
| 16 |
+
"dv", OpenAIChatCompletion(os.environ['OPENAI_MODEL_NAME'], api_key, org_id)
|
| 17 |
+
)
|
| 18 |
+
@sk_function(
|
| 19 |
+
description="Trả lời các câu hỏi liên quan đến thông tin thị trường năng lượng từ các báo cáo thị trường hằng ngày",
|
| 20 |
+
name="qdrant_request",
|
| 21 |
+
)
|
| 22 |
+
@sk_function_context_parameter(name="input", description="The raw question for querying")
|
| 23 |
+
async def RouteRequest(self, context: SKContext) -> str:
|
| 24 |
+
# Save the original user request
|
| 25 |
+
request = context["input"]
|
| 26 |
+
context["original_request"] = request
|
| 27 |
+
pluginsDirectory = "./functions/SK/plugins"
|
| 28 |
+
self.subKernel.import_semantic_skill_from_directory(pluginsDirectory, "QdrantSkill")
|
| 29 |
+
|
| 30 |
+
# Retrieve the intent from the user request
|
| 31 |
+
CreateResponse = self.subKernel.skills.get_function(
|
| 32 |
+
"QdrantSkill", "CreateResponse"
|
| 33 |
+
)
|
| 34 |
+
# print(f"Loaded 1st Function:\nFunction Name: {CreateResponse.name},\nFunction Description: {CreateResponse.description}\n")
|
| 35 |
+
|
| 36 |
+
# Prepare the functions to be called in the pipeline
|
| 37 |
+
self.subKernel.import_skill(QdrantQueryClass(self.subKernel), skill_name="QdrantQuery")
|
| 38 |
+
ContextQuery = self.subKernel.skills.get_function(
|
| 39 |
+
"QdrantQuery", "contextQueryPlan"
|
| 40 |
+
)
|
| 41 |
+
# print(f"Loaded 2nd Function:\nFunction Name: {ContextQuery.name},\nFunction Description: {ContextQuery.description}\n")
|
| 42 |
+
|
| 43 |
+
# Create a new context object with the original request
|
| 44 |
+
pipelineContext = self.subKernel.create_new_context()
|
| 45 |
+
pipelineContext["original_request"] = request
|
| 46 |
+
pipelineContext["input"] = request
|
| 47 |
+
|
| 48 |
+
# Run the functions in a pipeline
|
| 49 |
+
output = await self.subKernel.run_async(
|
| 50 |
+
ContextQuery,
|
| 51 |
+
CreateResponse,
|
| 52 |
+
input_context=pipelineContext,
|
| 53 |
+
)
|
| 54 |
+
return output['input']
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
|
functions/SK/plugins/QdrantSkill/__pycache__/QdrantQuery.cpython-311.pyc
ADDED
|
Binary file (2.77 kB). View file
|
|
|
functions/SK/plugins/QdrantSkill/__pycache__/QdrantQuery2.cpython-311.pyc
ADDED
|
Binary file (2.68 kB). View file
|
|
|
functions/SK/plugins/QdrantSkill/__pycache__/QdrantSkill.cpython-311.pyc
ADDED
|
Binary file (3.16 kB). View file
|
|
|
functions/SK/plugins/QdrantSkill/__pycache__/QdrantSkillPlanner.cpython-311.pyc
ADDED
|
Binary file (3.38 kB). View file
|
|
|
functions/SK/plugins/SQLskill/CreateResponse/config.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema": 1,
|
| 3 |
+
"type": "completion",
|
| 4 |
+
"description": "Creates a response based on the original request and the output of the pipeline",
|
| 5 |
+
"completion": {
|
| 6 |
+
"max_tokens": 2000,
|
| 7 |
+
"temperature": 0.0,
|
| 8 |
+
"top_p": 0.0,
|
| 9 |
+
"presence_penalty": 0.0,
|
| 10 |
+
"frequency_penalty": 0.0
|
| 11 |
+
},
|
| 12 |
+
"input": {
|
| 13 |
+
"parameters": [
|
| 14 |
+
{
|
| 15 |
+
"name": "input",
|
| 16 |
+
"description": "Results from query SQL database",
|
| 17 |
+
"defaultValue": ""
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"name": "original_request",
|
| 21 |
+
"description": "The original request from the user.",
|
| 22 |
+
"defaultValue": ""
|
| 23 |
+
}
|
| 24 |
+
]
|
| 25 |
+
}
|
| 26 |
+
}
|
functions/SK/plugins/SQLskill/CreateResponse/skprompt.txt
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
You will be provided with the original_request include an user question which is delimited by XML tags and
|
| 2 |
+
the information after querying a SQL databasse. This information related to the input question.
|
| 3 |
+
This information is delimited by triple Forward Slash.
|
| 4 |
+
|
| 5 |
+
<tag>{{$original_request}} </tag>\n
|
| 6 |
+
|
| 7 |
+
SQL QUERY COMMAND:
|
| 8 |
+
///{{$sql_query}}///
|
| 9 |
+
SQL QUERY RESULT:
|
| 10 |
+
///{{$input}}///
|
| 11 |
+
|
| 12 |
+
CREATE NATURAL LANGUAGE ANSWER FOR USER, BASING ON CONTEXT AND OBEY THE FOLLOWING RULES:
|
| 13 |
+
1. THE ANSƯER MUST BE A COMPLETE SENTENCE
|
| 14 |
+
2. ONLY USING INFORMATION FROM THE CONTEXT
|
| 15 |
+
3. IF CONTEXT IS NOT ENOUGH TO ANSWER THE QUESTION OR A SQL QUERY ERROR, RETURN "I DON'T KNOW" IN POLITE WAY USING THE SAME LANGUAGE AS original_request. FOR EXAMPLE: "original_request":"Các bài báo của tác giả Truong Van Nhan.", "answer":"Không tìm thấy tên tác giả Truong Van Nhan, hãy cung cấp chính xác tên tác giả."
|
functions/SK/plugins/SQLskill/CreateSQLQuery/config.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"schema": 1,
|
| 3 |
+
"type": "completion",
|
| 4 |
+
"description": "Create SQL query syntax basing on given schema and user question",
|
| 5 |
+
"completion": {
|
| 6 |
+
"max_tokens": 8000,
|
| 7 |
+
"temperature": 0.0,
|
| 8 |
+
"top_p": 0.0,
|
| 9 |
+
"presence_penalty": 0.0,
|
| 10 |
+
"frequency_penalty": 0.0
|
| 11 |
+
},
|
| 12 |
+
"input": {
|
| 13 |
+
"parameters": [
|
| 14 |
+
{
|
| 15 |
+
"name": "input",
|
| 16 |
+
"description": "SQL database schema",
|
| 17 |
+
"defaultValue": ""
|
| 18 |
+
},
|
| 19 |
+
{
|
| 20 |
+
"name": "original_request",
|
| 21 |
+
"description": "The original request from the user.",
|
| 22 |
+
"defaultValue": ""
|
| 23 |
+
}
|
| 24 |
+
]
|
| 25 |
+
}
|
| 26 |
+
}
|
functions/SK/plugins/SQLskill/CreateSQLQuery/skprompt.txt
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
You will be provided with the question and the database schema in the below json format, which for A is Table name in the system, B is column name, and C is Column data type
|
| 2 |
+
---
|
| 3 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagementEN]","B":"IssueID","C":"varchar"}
|
| 4 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagementEN]","B":"IssueNameEN","C":"varchar"}
|
| 5 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagementEN]","B":"AbstractEN","C":"varchar"}
|
| 6 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagementEN]","B":"KeywordsEN","C":"varchar"}
|
| 7 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"IssueID","C":"varchar"}
|
| 8 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"IssueNameVN","C":"varchar"}
|
| 9 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"DOI","C":"varchar"}
|
| 10 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"Language","C":"varchar"}
|
| 11 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"Domain","C":"varchar"}
|
| 12 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"JournalID","C":"varchar"}
|
| 13 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"IssuePageNumbers","C":"varchar"}
|
| 14 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"AbstractVN","C":"varchar"}
|
| 15 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"KeywordsVN","C":"varchar"}
|
| 16 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"ConclusionVN","C":"varchar"}
|
| 17 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"IssuePdfURL","C":"varchar"}
|
| 18 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"IssueDocURL","C":"varchar"}
|
| 19 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"DocVectorDB_URL","C":"varchar"}
|
| 20 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueManagement]","B":"FigureVectorDB_URL","C":"varchar"}
|
| 21 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[JournalManagement]","B":"JournalID","C":"varchar"}
|
| 22 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[JournalManagement]","B":"Volume","C":"varchar"}
|
| 23 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[JournalManagement]","B":"PublishedDate","C":"date"}
|
| 24 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[JournalManagement]","B":"EditorialDirector","C":"varchar"}
|
| 25 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[JournalManagement]","B":"VolumeURL","C":"varchar"}
|
| 26 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[FigureManagement]","B":"IssueID","C":"varchar"}
|
| 27 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[FigureManagement]","B":"FigName","C":"varchar"}
|
| 28 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[FigureManagement]","B":"FigType","C":"varchar"}
|
| 29 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[FigureManagement]","B":"FigInIssueOrder","C":"bigint"}
|
| 30 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[FigureManagement]","B":"FigURL","C":"varchar"}
|
| 31 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[AuthorManagement]","B":"AuthorName","C":"varchar"}
|
| 32 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[AuthorManagement]","B":"AuthorID","C":"varchar"}
|
| 33 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[AuthorManagement]","B":"AuthorEmail","C":"varchar"}
|
| 34 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[AuthorManagement]","B":"AuthorPhoneNumber","C":"varchar"}
|
| 35 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[AuthorManagement]","B":"AuthorOrganization","C":"varchar"}
|
| 36 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthos]","B":"IssueID","C":"varchar"}
|
| 37 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthos]","B":"IssueNameVN","C":"varchar"}
|
| 38 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthos]","B":"AuthorName","C":"varchar"}
|
| 39 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthos]","B":"AuthorID","C":"varchar"}
|
| 40 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthos]","B":"AuthorType","C":"varchar"}
|
| 41 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthors]","B":"IssueID","C":"varchar"}
|
| 42 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthors]","B":"IssueNameVN","C":"varchar"}
|
| 43 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthors]","B":"AuthorName","C":"varchar"}
|
| 44 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthors]","B":"AuthorID","C":"varchar"}
|
| 45 |
+
{"A":"[CSDL_TCDK_MAIN].[dbo].[IssueAuthors]","B":"AuthorType","C":"varchar"}
|
| 46 |
+
---
|
| 47 |
+
OBEY SOME RULES BELOW:
|
| 48 |
+
- GIVE SQL QUERY SYNTAX query database to answer user question: {{$input}}, basing on the schema.
|
| 49 |
+
- DONT EXPLAIN ANYTHING FURTHER
|
| 50 |
+
- DONT ASKBACK
|
| 51 |
+
- DONT GIVE COLUMNS NAME THAT DOES NOT APPEAR IN SCHEMA
|
functions/SK/plugins/SQLskill/SQLFunctions.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from sqlalchemy.sql import text
|
| 3 |
+
from sqlalchemy import create_engine
|
| 4 |
+
from sqlalchemy.orm import sessionmaker
|
| 5 |
+
|
| 6 |
+
from semantic_kernel import Kernel
|
| 7 |
+
from semantic_kernel.orchestration.sk_context import SKContext
|
| 8 |
+
from semantic_kernel.skill_definition import sk_function, sk_function_context_parameter
|
| 9 |
+
|
| 10 |
+
# Load environment variables from .env file
|
| 11 |
+
from dotenv import load_dotenv
|
| 12 |
+
load_dotenv()
|
| 13 |
+
|
| 14 |
+
class SQLGetQuery:
|
| 15 |
+
def __init__(self, kernel: Kernel):
|
| 16 |
+
self._kernel = kernel
|
| 17 |
+
|
| 18 |
+
@sk_function(
|
| 19 |
+
description="Query SQL database related to user question",
|
| 20 |
+
name="dbQuery",
|
| 21 |
+
)
|
| 22 |
+
@sk_function_context_parameter(name="input", description="SQL query related to user question which was generated by LLM")
|
| 23 |
+
def db_query(self, context: SKContext) -> str:
|
| 24 |
+
# Set SQLAlchemy logging level to WARNING
|
| 25 |
+
username = os.environ['USERNAME']
|
| 26 |
+
password = os.environ['PASSWORD']
|
| 27 |
+
driver = os.environ['DRIVER']
|
| 28 |
+
# schema = context['db_schema']
|
| 29 |
+
server = os.environ['CONNECTION_STRING']
|
| 30 |
+
database = os.environ['DB']
|
| 31 |
+
query = text(context['input'])
|
| 32 |
+
print(f"\n------------------\nSQL QUERY:\n {query}\n------------------\n")
|
| 33 |
+
connection_string = f'mssql+pyodbc://{username}:{password}@{server}/{database}?driver={driver}&TrustServerCertificate=no&Authentication=ActiveDirectoryPassword'
|
| 34 |
+
# Start query
|
| 35 |
+
engine = create_engine(connection_string, echo=False, connect_args={'auto_commit': True}, fast_executemany=True)
|
| 36 |
+
Session = sessionmaker(bind=engine)
|
| 37 |
+
session = Session()
|
| 38 |
+
# Execute the query and fetch the results
|
| 39 |
+
results = session.execute(query).fetchall()
|
| 40 |
+
results = str(results).strip()
|
| 41 |
+
#Update context
|
| 42 |
+
context['queryresult'] = results
|
| 43 |
+
context['db_string'] = server
|
| 44 |
+
context['db_name'] = database
|
| 45 |
+
context['sql_query'] = str(query)
|
| 46 |
+
print(f"\n------------------\nSQL RESULT:\n {results}\n------------------\n")
|
| 47 |
+
|
| 48 |
+
return results
|
functions/SK/plugins/SQLskill/SQLskill.py
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from semantic_kernel import Kernel
|
| 3 |
+
from semantic_kernel.orchestration.sk_context import SKContext
|
| 4 |
+
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion
|
| 5 |
+
from semantic_kernel.utils.settings import openai_settings_from_dot_env
|
| 6 |
+
from semantic_kernel.skill_definition import sk_function, sk_function_context_parameter
|
| 7 |
+
from .SQLFunctions import SQLGetQuery
|
| 8 |
+
|
| 9 |
+
# Load environment variables from .env file
|
| 10 |
+
from dotenv import load_dotenv
|
| 11 |
+
load_dotenv()
|
| 12 |
+
|
| 13 |
+
class SQLskill:
|
| 14 |
+
def __init__(self):
|
| 15 |
+
self._kernel = Kernel()
|
| 16 |
+
api_key, org_id = os.environ['OPENAI_API_KEY'], ""
|
| 17 |
+
self._kernel.add_text_completion_service(
|
| 18 |
+
"dv", OpenAIChatCompletion(os.environ['OPENAI_MODEL_NAME'], api_key, org_id)
|
| 19 |
+
)
|
| 20 |
+
@sk_function(
|
| 21 |
+
description="Routes the request to the appropriate function",
|
| 22 |
+
name="sql_request",
|
| 23 |
+
)
|
| 24 |
+
@sk_function_context_parameter(name="input", description="The raw question for querying")
|
| 25 |
+
async def RouteRequest(self, context: SKContext) -> str:
|
| 26 |
+
# Save the original user request
|
| 27 |
+
request = context["input"]
|
| 28 |
+
context["original_request"] = request
|
| 29 |
+
|
| 30 |
+
# Define plugins directory
|
| 31 |
+
pluginsDirectory = "./functions/SK/plugins"
|
| 32 |
+
self._kernel.import_semantic_skill_from_directory(pluginsDirectory, "SQLskill")
|
| 33 |
+
## Semantic Functions
|
| 34 |
+
CreateSQLQuery = self._kernel.skills.get_function("SQLskill", "CreateSQLQuery")
|
| 35 |
+
CreateSQLResponse = self._kernel.skills.get_function("SQLskill", "CreateResponse")
|
| 36 |
+
## Native Functions
|
| 37 |
+
self._kernel.import_skill(SQLGetQuery(self._kernel), skill_name="SQLGetQuery")
|
| 38 |
+
GetSQLResult = self._kernel.skills.get_function("SQLGetQuery", "dbQuery")
|
| 39 |
+
|
| 40 |
+
# Run the functions in a pipeline
|
| 41 |
+
output = await self._kernel.run_async(
|
| 42 |
+
CreateSQLQuery,
|
| 43 |
+
GetSQLResult,
|
| 44 |
+
CreateSQLResponse,
|
| 45 |
+
input_context=context,
|
| 46 |
+
)
|
| 47 |
+
return output["input"].replace("\n\n", "\n")
|
functions/SK/plugins/SQLskill/__pycache__/SQLFunctions.cpython-311.pyc
ADDED
|
Binary file (3.31 kB). View file
|
|
|
functions/SK/plugins/SQLskill/__pycache__/SQLskill.cpython-311.pyc
ADDED
|
Binary file (3.14 kB). View file
|
|
|
functions/__init__.py
ADDED
|
File without changes
|
functions/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (159 Bytes). View file
|
|
|
functions/__pycache__/csdl_tcdk.cpython-311.pyc
ADDED
|
Binary file (160 Bytes). View file
|
|
|
pages/01_CSDL TCDK.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from PIL import Image
|
| 2 |
+
import streamlit as st
|
| 3 |
+
|
| 4 |
+
from ui import *
|
| 5 |
+
from functions import *
|
| 6 |
+
|
| 7 |
+
logo = Image.open("./assets/images/logo.png")
|
| 8 |
+
st.set_page_config(# Alternate names: setup_page, page, layout
|
| 9 |
+
layout="wide", # Can be "centered" or "wide". In the future also "dashboard", etc.
|
| 10 |
+
initial_sidebar_state="auto", # Can be "auto", "expanded", "collapsed"
|
| 11 |
+
page_title="CSDL TCDK", # String or None. Strings get appended with "• Streamlit".
|
| 12 |
+
page_icon=logo, # String, anything supported by st.image, or None.
|
| 13 |
+
)
|
| 14 |
+
# --- LOAD CSS ---------------------------------------------------------------
|
| 15 |
+
with open("./style/style.css") as f:
|
| 16 |
+
st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True)
|
| 17 |
+
|
| 18 |
+
# --- UI CHATBOT -------------------------------------------------------------
|
| 19 |
+
chat_ui()
|
| 20 |
+
# --- UI SIDEBAR -------------------------------------------------------------
|
| 21 |
+
with st.sidebar:
|
| 22 |
+
context = """
|
| 23 |
+
Đây là chatbot hỏi đáp với CSDL bài báo Tạp chí Dầu khí.
|
| 24 |
+
|
| 25 |
+
Chatbot chỉ hỗ trợ hỏi đáp về các nội dung liên quan đến bài báo, nội dung bài báo, tác giả, năm xuất bản, tạp chí xuất bản, ...
|
| 26 |
+
|
| 27 |
+
Hãy đặt các câu hỏi cụ thể, dễ hiểu để chatbot có thể trả lời chính xác nhất.
|
| 28 |
+
|
| 29 |
+
Ví dụ:
|
| 30 |
+
- Có bao nhiêu bài báo trong cơ sở dữ liệu?
|
| 31 |
+
- Tác giả Trương Văn Nhân có bao nhiêu bài báo?
|
| 32 |
+
- Tên các bài báo của tác giả Trương Văn Nhân là gì?
|
| 33 |
+
|
| 34 |
+
Các câu hỏi liên quan đến nội dung bài báo cũng có thể được giải đáp:
|
| 35 |
+
- Phương pháp xử lý tín hiệu phi tuyến là gì?
|
| 36 |
+
"""
|
| 37 |
+
st.info(context)
|
pages/__init__.py
ADDED
|
File without changes
|
requirements.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
openai==0.27.8
|
| 2 |
+
streamlit==1.24.0
|
| 3 |
+
semantic-kernel==0.3.8.dev0
|
| 4 |
+
qdrant-client==1.3.1
|
| 5 |
+
cohere==4.18.0
|
| 6 |
+
python-dotenv==1.0.0
|
| 7 |
+
sqlalchemy==1.4.49
|
| 8 |
+
pyodbc==4.0.39
|
style/style.css
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
a {
|
| 2 |
+
text-decoration: none;
|
| 3 |
+
font-weight: 500;
|
| 4 |
+
}
|
| 5 |
+
|
| 6 |
+
.block-container {
|
| 7 |
+
padding-top: 0px;
|
| 8 |
+
padding-right: 10px;
|
| 9 |
+
padding-left: 10px;
|
| 10 |
+
}
|
| 11 |
+
|
| 12 |
+
a:hover {
|
| 13 |
+
text-decoration: none;
|
| 14 |
+
color: #d33682 !important;
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
ul {
|
| 18 |
+
list-style-type: none;
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
hr {
|
| 22 |
+
margin-top: 0;
|
| 23 |
+
margin-bottom: 5%;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
#MainMenu {
|
| 27 |
+
visibility: hidden;
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
footer {
|
| 31 |
+
visibility: hidden;
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
header {
|
| 35 |
+
visibility: hidden;
|
| 36 |
+
}
|
| 37 |
+
.css-9ycgxx.eqdbnj012 {
|
| 38 |
+
display: none;
|
| 39 |
+
}
|
| 40 |
+
.css-1aehpvj.eex3ynb0 {
|
| 41 |
+
display: none;
|
| 42 |
+
}
|
| 43 |
+
.css-vjj2ce.eqdbnj015 {
|
| 44 |
+
padding: 0;
|
| 45 |
+
width: 160px;
|
| 46 |
+
}
|
| 47 |
+
.css-et4mjn.esravye0 {
|
| 48 |
+
gap: 0;
|
| 49 |
+
}
|
| 50 |
+
/* .css-5rimss.eqr7zpz4 {
|
| 51 |
+
color: #22A699;
|
| 52 |
+
} */
|
| 53 |
+
.css-pmz2b6.esravye0 {
|
| 54 |
+
gap: 0;
|
| 55 |
+
}
|
| 56 |
+
.css-soq042.esravye0 {
|
| 57 |
+
border: 0.5px solid rgba(49, 51, 63, 0.1);
|
| 58 |
+
}
|
| 59 |
+
.css-u8hs99.eqdbnj014 {
|
| 60 |
+
background-color: rgba(240, 242, 246, 0.5);
|
| 61 |
+
}
|
| 62 |
+
.st-bf.st-ca.st-cy.st-bw.st-bx.st-bu {
|
| 63 |
+
padding: 0;
|
| 64 |
+
}
|
| 65 |
+
.css-pkbazv.e1akgbir5{
|
| 66 |
+
color: rgb(186, 38, 15);
|
| 67 |
+
}
|
| 68 |
+
.css-17lntkn.e1akgbir5{
|
| 69 |
+
color: rgb(15, 110, 193);
|
| 70 |
+
}
|
ui/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
from .ui_csdltcdk import *
|
ui/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (188 Bytes). View file
|
|
|
ui/__pycache__/ui_csdltcdk.cpython-311.pyc
ADDED
|
Binary file (4.19 kB). View file
|
|
|
ui/ui_csdltcdk.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import openai
|
| 3 |
+
import asyncio
|
| 4 |
+
import streamlit as st
|
| 5 |
+
from functions.SK.TCDKPlanner import main_tcdk
|
| 6 |
+
# --- ADD LOGO ------------------------------------------------------------------
|
| 7 |
+
def add_logo():
|
| 8 |
+
st.markdown(
|
| 9 |
+
"""
|
| 10 |
+
<style>
|
| 11 |
+
[data-testid="stSidebarNav"] {
|
| 12 |
+
background-image: url(https://i.ibb.co/LPp2TTB/logo.png);
|
| 13 |
+
background-repeat: no-repeat;
|
| 14 |
+
background-size: 230px 230px;
|
| 15 |
+
padding-top: 120px;
|
| 16 |
+
padding-left: 10px;
|
| 17 |
+
background-position: 20px 20x;
|
| 18 |
+
}
|
| 19 |
+
[data-testid="stSidebarNav"]::before {
|
| 20 |
+
content: "VPI-Sage";
|
| 21 |
+
margin-left: 20px;
|
| 22 |
+
margin-top: 20px;
|
| 23 |
+
font-size: 30px;
|
| 24 |
+
position: relative;
|
| 25 |
+
top: 100px;
|
| 26 |
+
font: 30px sans-serif;
|
| 27 |
+
color: rgb(186, 38, 15);
|
| 28 |
+
text-align: center;
|
| 29 |
+
}
|
| 30 |
+
</style>
|
| 31 |
+
""",
|
| 32 |
+
unsafe_allow_html=True,
|
| 33 |
+
)
|
| 34 |
+
|
| 35 |
+
def chat_ui():
|
| 36 |
+
openai.api_key = os.environ["OPENAI_API_KEY"]
|
| 37 |
+
|
| 38 |
+
if "openai_model" not in st.session_state:
|
| 39 |
+
st.session_state["openai_model"] = os.environ["OPENAI_MODEL_NAME"]
|
| 40 |
+
|
| 41 |
+
if "messages" not in st.session_state:
|
| 42 |
+
st.session_state.messages = []
|
| 43 |
+
|
| 44 |
+
for message in st.session_state.messages:
|
| 45 |
+
with st.chat_message(message["role"]):
|
| 46 |
+
st.markdown(message["content"])
|
| 47 |
+
|
| 48 |
+
generated_plan = None
|
| 49 |
+
if prompt := st.chat_input("Nhập câu hỏi của bạn"):
|
| 50 |
+
st.session_state.messages.append({"role": "user", "content": prompt})
|
| 51 |
+
with st.chat_message("user"):
|
| 52 |
+
st.markdown(prompt)
|
| 53 |
+
|
| 54 |
+
with st.chat_message("assistant"):
|
| 55 |
+
message_placeholder = st.empty()
|
| 56 |
+
full_response = ""
|
| 57 |
+
|
| 58 |
+
# SK here
|
| 59 |
+
## ---------------------------------------------------------------
|
| 60 |
+
with st.spinner(text='...'):
|
| 61 |
+
generated_plan, results = asyncio.run(main_tcdk(prompt))
|
| 62 |
+
## ---------------------------------------------------------------
|
| 63 |
+
# Save to ui response here
|
| 64 |
+
full_response += results
|
| 65 |
+
## ---------------------------------------------------------------
|
| 66 |
+
message_placeholder.markdown(full_response + "▌")
|
| 67 |
+
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
| 68 |
+
|
| 69 |
+
refer_expander = st.expander("Planner")
|
| 70 |
+
if generated_plan is not None:
|
| 71 |
+
with refer_expander:
|
| 72 |
+
st.text_area('-',
|
| 73 |
+
generated_plan,
|
| 74 |
+
height=300,
|
| 75 |
+
label_visibility="collapsed",
|
| 76 |
+
)
|