Spaces:
Sleeping
Sleeping
Commit ·
e4b5ea4
1
Parent(s): 0338c58
feat: update demo to pinsmart revamp
Browse files- .env.example +2 -4
- app.py +100 -84
- config.py +3 -5
- poetry.lock +0 -0
- prompts.py +68 -0
- pyproject.toml +4 -0
- requirements.txt +27 -1
- schemas.py +0 -77
.env.example
CHANGED
|
@@ -1,4 +1,2 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
CACHE_RESPONSE_TOKEN="asd"
|
| 4 |
-
CACHE_RESPONSE_URL="recom-calc-url"
|
|
|
|
| 1 |
+
OPENAI_API_KEY=asdasdasd
|
| 2 |
+
ES_URL=asdasdsad
|
|
|
|
|
|
app.py
CHANGED
|
@@ -1,106 +1,122 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
import gradio as gr
|
| 4 |
-
import
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5 |
|
| 6 |
from config import get_settings
|
| 7 |
-
from
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
)
|
| 13 |
-
import logging
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
def index_faq(chatbot_qa_object: ChatbotQuestionAnswer):
|
| 17 |
-
data = PropertyKnowledgeIndexFAQRequest(
|
| 18 |
-
question=PropertyKnowledgeQuestionWithTokenObject(
|
| 19 |
-
token=chatbot_qa_object.question.token,
|
| 20 |
-
content=chatbot_qa_object.question.content,
|
| 21 |
-
embedding=chatbot_qa_object.question.embedding,
|
| 22 |
-
modelName=chatbot_qa_object.question.model_name,
|
| 23 |
-
),
|
| 24 |
-
answer=PropertyKnowledgeAnswerObject(
|
| 25 |
-
content=chatbot_qa_object.answer.content,
|
| 26 |
-
categories=chatbot_qa_object.answer.categories,
|
| 27 |
-
source=chatbot_qa_object.answer.source,
|
| 28 |
-
referenceURLs=chatbot_qa_object.answer.reference_urls,
|
| 29 |
-
modelName=chatbot_qa_object.answer.model_name,
|
| 30 |
-
),
|
| 31 |
-
)
|
| 32 |
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 45 |
)
|
| 46 |
|
|
|
|
|
|
|
|
|
|
| 47 |
|
| 48 |
-
def get_prompt_response(message: str):
|
| 49 |
-
data = {"question": message}
|
| 50 |
-
response = requests.post(
|
| 51 |
-
get_settings().chat_response_url,
|
| 52 |
-
headers={
|
| 53 |
-
"Authorization": "Bearer" f" {get_settings().chat_response_token}",
|
| 54 |
-
"Content-Type": "application/json",
|
| 55 |
-
},
|
| 56 |
-
json=data,
|
| 57 |
-
)
|
| 58 |
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
response.json()["data"]
|
| 63 |
-
)
|
| 64 |
-
except ValueError as val_err:
|
| 65 |
-
logging.error(
|
| 66 |
-
f"got value on chatbot response: {response.text},"
|
| 67 |
-
f"error message: {val_err}"
|
| 68 |
-
)
|
| 69 |
|
| 70 |
-
return "Terjadi kesalahan, silakan coba kembali"
|
| 71 |
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
f"got unknown error on chabot find answer request, error: {e}"
|
| 75 |
-
)
|
| 76 |
|
| 77 |
-
return "Terjadi kesalahan, silakan coba kembali"
|
| 78 |
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
|
| 85 |
-
if len(chatbot_qa_object.answer.reference_urls) > 0:
|
| 86 |
-
bot_msg = chatbot_qa_object.answer.content + "\n\n" + "Sumber: \n"
|
| 87 |
|
| 88 |
-
|
| 89 |
-
|
| 90 |
|
| 91 |
-
|
| 92 |
|
| 93 |
-
|
| 94 |
|
| 95 |
-
if response.status_code == HTTPStatus.NOT_FOUND:
|
| 96 |
-
return "Maaf, saya tidak dapat menemukan jawaban untuk pertanyaan ini."
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 102 |
|
| 103 |
-
return
|
| 104 |
|
| 105 |
|
| 106 |
def chat(message, history):
|
|
@@ -124,7 +140,7 @@ with gr.Blocks() as demo:
|
|
| 124 |
"
|
| 125 |
>
|
| 126 |
<h1 style="font-weight: 900; margin-bottom: 7px; margin-top: 5px;">
|
| 127 |
-
|
| 128 |
</h1>
|
| 129 |
</div>
|
| 130 |
</div>"""
|
|
@@ -133,7 +149,7 @@ with gr.Blocks() as demo:
|
|
| 133 |
with gr.Row():
|
| 134 |
question = gr.Textbox(
|
| 135 |
label=(
|
| 136 |
-
"Masukkan pertanyaan seputar
|
| 137 |
" dsb)",
|
| 138 |
),
|
| 139 |
placeholder="Apa dokumen yang diperlukan untuk KPR?",
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
|
| 3 |
+
# Suppress all UserWarnings
|
| 4 |
+
import warnings
|
| 5 |
+
from typing import Any
|
| 6 |
|
| 7 |
import gradio as gr
|
| 8 |
+
from langchain.retrievers import ContextualCompressionRetriever
|
| 9 |
+
from langchain.retrievers.document_compressors import LLMChainFilter
|
| 10 |
+
from langchain.schema import StrOutputParser
|
| 11 |
+
from langchain_community.vectorstores.elasticsearch import ElasticsearchStore
|
| 12 |
+
from langchain_core.documents import Document
|
| 13 |
+
from langchain_core.prompts import ChatPromptTemplate
|
| 14 |
+
from langchain_core.runnables import RunnablePassthrough
|
| 15 |
+
from langchain_core.runnables.base import RunnableSerializable
|
| 16 |
+
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
|
| 17 |
|
| 18 |
from config import get_settings
|
| 19 |
+
from prompts import CONTEXT_TEMPLATE, QA_WITH_CONTEXT_PROMPT, SYSTEM_PROMPT
|
| 20 |
+
|
| 21 |
+
warnings.filterwarnings("ignore", category=UserWarning)
|
| 22 |
+
|
| 23 |
+
KNOWLEDGE_BASE_INDEX_NAME = "pinsmart_revamp_prototype"
|
| 24 |
+
EMBEDDING_MODEL = "text-embedding-3-large"
|
| 25 |
+
RAG_LLM_MODEL = "gpt-3.5-turbo-0125"
|
| 26 |
+
NROF_RETRIEVED_CONTEXT = 5
|
| 27 |
+
|
| 28 |
+
ERROR_MESSAGE = "Terjadi kesalahan, silakan coba kembali"
|
| 29 |
+
|
| 30 |
+
# ES only support up to 2048 embedding dimension
|
| 31 |
+
embeddings = OpenAIEmbeddings(
|
| 32 |
+
model=EMBEDDING_MODEL,
|
| 33 |
+
api_key=get_settings().openai_api_key,
|
| 34 |
+
dimensions=2048,
|
| 35 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
+
vector_db = ElasticsearchStore(
|
| 38 |
+
es_url=get_settings().es_url,
|
| 39 |
+
index_name=KNOWLEDGE_BASE_INDEX_NAME,
|
| 40 |
+
embedding=embeddings,
|
| 41 |
+
)
|
| 42 |
+
|
| 43 |
+
llm = ChatOpenAI(
|
| 44 |
+
model_name=RAG_LLM_MODEL,
|
| 45 |
+
temperature=0,
|
| 46 |
+
api_key=get_settings().openai_api_key,
|
| 47 |
+
)
|
| 48 |
+
|
| 49 |
+
qa_prompt = ChatPromptTemplate.from_messages(
|
| 50 |
+
[
|
| 51 |
+
("system", SYSTEM_PROMPT),
|
| 52 |
+
("human", QA_WITH_CONTEXT_PROMPT),
|
| 53 |
+
]
|
| 54 |
+
)
|
| 55 |
+
|
| 56 |
+
_filter = LLMChainFilter.from_llm(llm)
|
| 57 |
+
docs_retriever = vector_db.as_retriever(
|
| 58 |
+
search_kwargs={"k": NROF_RETRIEVED_CONTEXT}
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def format_contexts(docs: list[Document]) -> str:
|
| 63 |
+
aggregate_context = ""
|
| 64 |
+
for doc in docs:
|
| 65 |
+
context = CONTEXT_TEMPLATE.format(
|
| 66 |
+
source=doc.metadata["document_id"],
|
| 67 |
+
title=doc.metadata["heading_title"],
|
| 68 |
+
content=doc.page_content,
|
| 69 |
)
|
| 70 |
|
| 71 |
+
aggregate_context += context
|
| 72 |
+
|
| 73 |
+
return aggregate_context
|
| 74 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
+
docs_compression_retriever = ContextualCompressionRetriever(
|
| 77 |
+
base_compressor=_filter, base_retriever=docs_retriever
|
| 78 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
|
|
|
|
| 80 |
|
| 81 |
+
def get_end_device_target(*args: Any) -> str:
|
| 82 |
+
return "mobile"
|
|
|
|
|
|
|
| 83 |
|
|
|
|
| 84 |
|
| 85 |
+
rag_chain: RunnableSerializable = (
|
| 86 |
+
{
|
| 87 |
+
"context": docs_compression_retriever | format_contexts,
|
| 88 |
+
"device": get_end_device_target,
|
| 89 |
+
"question": RunnablePassthrough(),
|
| 90 |
+
}
|
| 91 |
+
| qa_prompt
|
| 92 |
+
| llm
|
| 93 |
+
| StrOutputParser()
|
| 94 |
+
)
|
| 95 |
|
|
|
|
|
|
|
| 96 |
|
| 97 |
+
def parse_response(response: str) -> tuple[str, list[dict]]:
|
| 98 |
+
answer = response.split("[ANSWER]")[1].split("[RELATED DOCS]")[0].strip()
|
| 99 |
|
| 100 |
+
related_docs = json.loads(response.split("[RELATED DOCS]")[1].strip())
|
| 101 |
|
| 102 |
+
return answer, related_docs
|
| 103 |
|
|
|
|
|
|
|
| 104 |
|
| 105 |
+
def get_prompt_response(message: str):
|
| 106 |
+
response = rag_chain.invoke(message)
|
| 107 |
+
|
| 108 |
+
try:
|
| 109 |
+
answer, related_docs = parse_response(response)
|
| 110 |
+
except Exception as e:
|
| 111 |
+
print(f"Error : {e}")
|
| 112 |
+
return ERROR_MESSAGE
|
| 113 |
+
|
| 114 |
+
reference_str = "Referensi: \n"
|
| 115 |
+
for doc in related_docs:
|
| 116 |
+
reference_title = doc["title"]
|
| 117 |
+
reference_str += f"- Artikel: {reference_title}\n"
|
| 118 |
|
| 119 |
+
return answer + "\n\n" + reference_str
|
| 120 |
|
| 121 |
|
| 122 |
def chat(message, history):
|
|
|
|
| 140 |
"
|
| 141 |
>
|
| 142 |
<h1 style="font-weight: 900; margin-bottom: 7px; margin-top: 5px;">
|
| 143 |
+
PinSmart Prototype
|
| 144 |
</h1>
|
| 145 |
</div>
|
| 146 |
</div>"""
|
|
|
|
| 149 |
with gr.Row():
|
| 150 |
question = gr.Textbox(
|
| 151 |
label=(
|
| 152 |
+
"Masukkan pertanyaan seputar properti (KPR, Take Over KPR,"
|
| 153 |
" dsb)",
|
| 154 |
),
|
| 155 |
placeholder="Apa dokumen yang diperlukan untuk KPR?",
|
config.py
CHANGED
|
@@ -4,13 +4,11 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
| 4 |
|
| 5 |
|
| 6 |
class Settings(BaseSettings):
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
cache_response_url: str
|
| 10 |
-
cache_response_token: str
|
| 11 |
|
| 12 |
model_config = SettingsConfigDict(
|
| 13 |
-
env_file=".env", env_file_encoding="utf-8"
|
| 14 |
)
|
| 15 |
|
| 16 |
|
|
|
|
| 4 |
|
| 5 |
|
| 6 |
class Settings(BaseSettings):
|
| 7 |
+
openai_api_key: str
|
| 8 |
+
es_url: str
|
|
|
|
|
|
|
| 9 |
|
| 10 |
model_config = SettingsConfigDict(
|
| 11 |
+
env_file=".env", env_file_encoding="utf-8", extra="ignore"
|
| 12 |
)
|
| 13 |
|
| 14 |
|
poetry.lock
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
prompts.py
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SYSTEM_PROMPT = (
|
| 2 |
+
"You are a world class property consultant for Indonesia market recognized"
|
| 3 |
+
" as PinSmart. You work for Pinhome.id and hence cannot mention other "
|
| 4 |
+
"competitor such as rumah.com, rumah123.com, lamudi.id, 99.co, and so on."
|
| 5 |
+
)
|
| 6 |
+
QA_WITH_CONTEXT_PROMPT = """
|
| 7 |
+
## Instructions
|
| 8 |
+
|
| 9 |
+
- Always generate answer only based on the contexts and facts
|
| 10 |
+
- Take your time to generate the answer and elaborate all the supporting
|
| 11 |
+
details in the answer
|
| 12 |
+
- The generated response MUST use the following format:
|
| 13 |
+
```
|
| 14 |
+
[ANSWER]
|
| 15 |
+
put the answer here
|
| 16 |
+
|
| 17 |
+
[RELATED DOCS]
|
| 18 |
+
[
|
| 19 |
+
{{
|
| 20 |
+
"source" : "context_source1",
|
| 21 |
+
"title" : "context_title1"
|
| 22 |
+
}},
|
| 23 |
+
{{
|
| 24 |
+
"source" : "context_source2",
|
| 25 |
+
"title" : "context_title2"
|
| 26 |
+
}},
|
| 27 |
+
...
|
| 28 |
+
]
|
| 29 |
+
```
|
| 30 |
+
- Only show [RELATED DOCS] that is exist on the provided context and do
|
| 31 |
+
not show duplicate [RELATED DOCS]
|
| 32 |
+
- Always generate [ANSWER] in Indonesian language
|
| 33 |
+
- Generate the [ANSWER] using the following formatting rules:
|
| 34 |
+
- Must be easy to read and using good structure such as
|
| 35 |
+
bullet and numbering if necessary
|
| 36 |
+
- Use the best string formatting if the [ANSWER] is shown in
|
| 37 |
+
{device} app as chatbot app
|
| 38 |
+
|
| 39 |
+
## Contexts
|
| 40 |
+
{context}
|
| 41 |
+
|
| 42 |
+
## Question
|
| 43 |
+
{question}
|
| 44 |
+
|
| 45 |
+
## Answer
|
| 46 |
+
"""
|
| 47 |
+
|
| 48 |
+
CONTEXT_TEMPLATE = """
|
| 49 |
+
---
|
| 50 |
+
### Context Metadata
|
| 51 |
+
source: {source}
|
| 52 |
+
title: {title}
|
| 53 |
+
|
| 54 |
+
### Content
|
| 55 |
+
|
| 56 |
+
{content}
|
| 57 |
+
"""
|
| 58 |
+
|
| 59 |
+
CONTEXT_TEMPLATE = """
|
| 60 |
+
---
|
| 61 |
+
### Context Metadata
|
| 62 |
+
source: {source}
|
| 63 |
+
title: {title}
|
| 64 |
+
|
| 65 |
+
### Content
|
| 66 |
+
|
| 67 |
+
{content}
|
| 68 |
+
"""
|
pyproject.toml
CHANGED
|
@@ -10,6 +10,10 @@ packages = []
|
|
| 10 |
python = "^3.10"
|
| 11 |
gradio = { version = "3.44.3", source = "pypi" }
|
| 12 |
pydantic-settings = { version = "^2.0.3", extras = ["dotenv"], source = "pypi" }
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
|
| 15 |
[tool.ruff]
|
|
|
|
| 10 |
python = "^3.10"
|
| 11 |
gradio = { version = "3.44.3", source = "pypi" }
|
| 12 |
pydantic-settings = { version = "^2.0.3", extras = ["dotenv"], source = "pypi" }
|
| 13 |
+
langchain = {version = "^0.1.7", source = "pypi"}
|
| 14 |
+
langchain-openai = {version = "^0.0.6", source = "pypi"}
|
| 15 |
+
tiktoken = {version = "^0.6.0", source = "pypi"}
|
| 16 |
+
elasticsearch = {version = "^8.12.0", source = "pypi"}
|
| 17 |
|
| 18 |
|
| 19 |
[tool.ruff]
|
requirements.txt
CHANGED
|
@@ -1,7 +1,10 @@
|
|
| 1 |
aiofiles==23.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
|
|
|
| 2 |
altair==5.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 3 |
annotated-types==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 4 |
anyio==4.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 5 |
attrs==23.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 6 |
certifi==2023.7.22 ; python_version >= "3.10" and python_version < "4.0"
|
| 7 |
charset-normalizer==3.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
@@ -9,14 +12,20 @@ click==8.1.7 ; python_version >= "3.10" and python_version < "4.0"
|
|
| 9 |
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
|
| 10 |
contourpy==1.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 11 |
cycler==0.11.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
exceptiongroup==1.1.3 ; python_version >= "3.10" and python_version < "3.11"
|
| 13 |
fastapi==0.103.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 14 |
ffmpy==0.3.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 15 |
filelock==3.12.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 16 |
fonttools==4.42.1 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 17 |
fsspec==2023.9.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 18 |
gradio-client==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 19 |
gradio==3.44.3 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 20 |
h11==0.14.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 21 |
httpcore==0.18.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 22 |
httpx==0.25.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
@@ -24,14 +33,25 @@ huggingface-hub==0.17.1 ; python_version >= "3.10" and python_version < "4.0"
|
|
| 24 |
idna==3.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 25 |
importlib-resources==6.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 26 |
jinja2==3.1.2 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
|
|
|
| 27 |
jsonschema-specifications==2023.7.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 28 |
jsonschema==4.19.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 29 |
kiwisolver==1.4.5 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 31 |
matplotlib==3.8.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
|
|
|
| 32 |
numpy==1.25.2 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 33 |
orjson==3.9.7 ; python_version >= "3.10" and python_version < "4.0"
|
| 34 |
-
packaging==23.
|
| 35 |
pandas==2.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 36 |
pillow==10.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 37 |
pydantic-core==2.6.3 ; python_version >= "3.10" and python_version < "4.0"
|
|
@@ -45,6 +65,7 @@ python-multipart==0.0.6 ; python_version >= "3.10" and python_version < "4.0"
|
|
| 45 |
pytz==2023.3.post1 ; python_version >= "3.10" and python_version < "4.0"
|
| 46 |
pyyaml==6.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 47 |
referencing==0.30.2 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 48 |
requests==2.31.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 49 |
rpds-py==0.10.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 50 |
semantic-version==2.10.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
@@ -52,12 +73,17 @@ setuptools-scm==7.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
| 52 |
setuptools==68.2.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 53 |
six==1.16.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 54 |
sniffio==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 55 |
starlette==0.27.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
|
|
|
| 56 |
tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11"
|
| 57 |
toolz==0.12.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 58 |
tqdm==4.66.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 59 |
typing-extensions==4.7.1 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 60 |
tzdata==2023.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 61 |
urllib3==2.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 62 |
uvicorn==0.23.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 63 |
websockets==11.0.3 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
|
|
| 1 |
aiofiles==23.2.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 2 |
+
aiohttp==3.9.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 3 |
+
aiosignal==1.3.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 4 |
altair==5.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 5 |
annotated-types==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 6 |
anyio==4.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 7 |
+
async-timeout==4.0.3 ; python_version >= "3.10" and python_version < "3.11"
|
| 8 |
attrs==23.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 9 |
certifi==2023.7.22 ; python_version >= "3.10" and python_version < "4.0"
|
| 10 |
charset-normalizer==3.2.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 12 |
colorama==0.4.6 ; python_version >= "3.10" and python_version < "4.0" and platform_system == "Windows"
|
| 13 |
contourpy==1.1.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 14 |
cycler==0.11.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 15 |
+
dataclasses-json==0.6.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 16 |
+
distro==1.9.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 17 |
+
elastic-transport==8.12.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 18 |
+
elasticsearch==8.12.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 19 |
exceptiongroup==1.1.3 ; python_version >= "3.10" and python_version < "3.11"
|
| 20 |
fastapi==0.103.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 21 |
ffmpy==0.3.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 22 |
filelock==3.12.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 23 |
fonttools==4.42.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 24 |
+
frozenlist==1.4.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 25 |
fsspec==2023.9.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 26 |
gradio-client==0.5.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 27 |
gradio==3.44.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 28 |
+
greenlet==3.0.3 ; python_version >= "3.10" and python_version < "4.0" and (platform_machine == "win32" or platform_machine == "WIN32" or platform_machine == "AMD64" or platform_machine == "amd64" or platform_machine == "x86_64" or platform_machine == "ppc64le" or platform_machine == "aarch64")
|
| 29 |
h11==0.14.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 30 |
httpcore==0.18.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 31 |
httpx==0.25.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 33 |
idna==3.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 34 |
importlib-resources==6.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 35 |
jinja2==3.1.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 36 |
+
jsonpatch==1.33 ; python_version >= "3.10" and python_version < "4.0"
|
| 37 |
+
jsonpointer==2.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 38 |
jsonschema-specifications==2023.7.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 39 |
jsonschema==4.19.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 40 |
kiwisolver==1.4.5 ; python_version >= "3.10" and python_version < "4.0"
|
| 41 |
+
langchain-community==0.0.20 ; python_version >= "3.10" and python_version < "4.0"
|
| 42 |
+
langchain-core==0.1.23 ; python_version >= "3.10" and python_version < "4.0"
|
| 43 |
+
langchain-openai==0.0.6 ; python_version >= "3.10" and python_version < "4.0"
|
| 44 |
+
langchain==0.1.7 ; python_version >= "3.10" and python_version < "4.0"
|
| 45 |
+
langsmith==0.0.87 ; python_version >= "3.10" and python_version < "4.0"
|
| 46 |
markupsafe==2.1.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 47 |
+
marshmallow==3.20.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 48 |
matplotlib==3.8.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 49 |
+
multidict==6.0.5 ; python_version >= "3.10" and python_version < "4.0"
|
| 50 |
+
mypy-extensions==1.0.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 51 |
numpy==1.25.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 52 |
+
openai==1.12.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 53 |
orjson==3.9.7 ; python_version >= "3.10" and python_version < "4.0"
|
| 54 |
+
packaging==23.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 55 |
pandas==2.1.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 56 |
pillow==10.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 57 |
pydantic-core==2.6.3 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 65 |
pytz==2023.3.post1 ; python_version >= "3.10" and python_version < "4.0"
|
| 66 |
pyyaml==6.0.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 67 |
referencing==0.30.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 68 |
+
regex==2023.12.25 ; python_version >= "3.10" and python_version < "4.0"
|
| 69 |
requests==2.31.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 70 |
rpds-py==0.10.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 71 |
semantic-version==2.10.0 ; python_version >= "3.10" and python_version < "4.0"
|
|
|
|
| 73 |
setuptools==68.2.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 74 |
six==1.16.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 75 |
sniffio==1.3.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 76 |
+
sqlalchemy==2.0.27 ; python_version >= "3.10" and python_version < "4.0"
|
| 77 |
starlette==0.27.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 78 |
+
tenacity==8.2.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 79 |
+
tiktoken==0.6.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 80 |
tomli==2.0.1 ; python_version >= "3.10" and python_version < "3.11"
|
| 81 |
toolz==0.12.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 82 |
tqdm==4.66.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 83 |
typing-extensions==4.7.1 ; python_version >= "3.10" and python_version < "4.0"
|
| 84 |
+
typing-inspect==0.9.0 ; python_version >= "3.10" and python_version < "4.0"
|
| 85 |
tzdata==2023.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 86 |
urllib3==2.0.4 ; python_version >= "3.10" and python_version < "4.0"
|
| 87 |
uvicorn==0.23.2 ; python_version >= "3.10" and python_version < "4.0"
|
| 88 |
websockets==11.0.3 ; python_version >= "3.10" and python_version < "4.0"
|
| 89 |
+
yarl==1.9.4 ; python_version >= "3.10" and python_version < "4.0"
|
schemas.py
DELETED
|
@@ -1,77 +0,0 @@
|
|
| 1 |
-
from typing import Optional
|
| 2 |
-
from pydantic import BaseModel, Field, validator
|
| 3 |
-
from enum import Enum
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
class ChatbotQuestion(BaseModel):
|
| 7 |
-
token: str = Field(..., alias="token")
|
| 8 |
-
content: str = Field(..., alias="content")
|
| 9 |
-
embedding: Optional[list[float]] = Field(None, alias="embedding")
|
| 10 |
-
model_name: str = Field(..., alias="modelName")
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
class ChatbotAnswer(BaseModel):
|
| 14 |
-
token: str = Field(..., alias="token")
|
| 15 |
-
content: str = Field(..., alias="content")
|
| 16 |
-
reference_urls: list[str] = Field(..., alias="referenceURLs")
|
| 17 |
-
categories: list[str] = Field(..., alias="categories")
|
| 18 |
-
source: str = Field(..., alias="source")
|
| 19 |
-
model_name: str = Field(..., alias="modelName")
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
class ChatbotQuestionAnswer(BaseModel):
|
| 23 |
-
question: ChatbotQuestion = Field(..., alias="question")
|
| 24 |
-
answer: ChatbotAnswer = Field(..., alias="answer")
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
class CategoriesObject(Enum):
|
| 28 |
-
property_seekers = "property_seekers"
|
| 29 |
-
property_owners = "property_owners"
|
| 30 |
-
mortgage = "mortgage"
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
class SourcesObject(Enum):
|
| 34 |
-
manual = "manual"
|
| 35 |
-
chatbot = "chatbot"
|
| 36 |
-
knowledge_docs_unavailable = "knowledge_docs_unavailable"
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
class PropertyKnowledgeAnswerObject(BaseModel):
|
| 40 |
-
content: str
|
| 41 |
-
categories: list[CategoriesObject] = Field([])
|
| 42 |
-
source: SourcesObject
|
| 43 |
-
reference_urls: list[str] = Field([], alias="referenceURLs")
|
| 44 |
-
model_name: Optional[str] = Field(None, alias="modelName")
|
| 45 |
-
|
| 46 |
-
@validator("content")
|
| 47 |
-
def validate_answer_content(cls, content: str) -> dict:
|
| 48 |
-
if content == "":
|
| 49 |
-
raise ValueError("content can't be empty string")
|
| 50 |
-
|
| 51 |
-
return content
|
| 52 |
-
|
| 53 |
-
@validator("model_name")
|
| 54 |
-
def validate_answer_model_name(cls, model_name: str) -> dict:
|
| 55 |
-
if model_name is not None and model_name == "":
|
| 56 |
-
return None
|
| 57 |
-
|
| 58 |
-
return model_name
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
class PropertyKnowledgeQuestionWithTokenObject(BaseModel):
|
| 62 |
-
token: Optional[str]
|
| 63 |
-
content: str
|
| 64 |
-
embedding: Optional[list[float]] = Field([])
|
| 65 |
-
model_name: Optional[str] = Field(None, alias="modelName")
|
| 66 |
-
|
| 67 |
-
@validator("content")
|
| 68 |
-
def validate_question_content(cls, content: str) -> dict:
|
| 69 |
-
if content == "":
|
| 70 |
-
raise ValueError("content can't be empty string")
|
| 71 |
-
|
| 72 |
-
return content
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
class PropertyKnowledgeIndexFAQRequest(BaseModel):
|
| 76 |
-
question: PropertyKnowledgeQuestionWithTokenObject
|
| 77 |
-
answer: PropertyKnowledgeAnswerObject
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|