Commit e18aa9a8 authored by server1's avatar server1
Browse files

KHANHNQ: init service openai

parents
Pipeline #452 failed with stages
in 0 seconds
export OPENAI_API_KEY="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"
export RABBITMQ_HOST=192.168.1.241
export RABBITMQ_PORT=5672
export RABBITMQ_VIRTUAL_HOST=vhost
export RABBITMQ_USERNAME=khanhnq
export RABBITMQ_PASSWORD=eYVX7EwVmmxKPCDmwMtyKVge8oLd2t81
export RABBITMQ_DURABLE=true
\ No newline at end of file
### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
### Python Patch ###
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
poetry.toml
# ruff
.ruff_cache/
# LSP config files
pyrightconfig.json
### Redis ###
# Ignore redis binary dump (dump.rdb) files
*.rdb
### SQLLite ###
*.db
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/
# Built Visual Studio Code Extensions
*.vsix
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
.ionide
# Log folder
/logs/
# Record files
/records/
/records_vaapi/
/records_dash/
/exports/
\ No newline at end of file
[submodule "commonkit"]
path = commonkit
url = git@github.com:nquockhanh0209/commonkit.git
import io
import time
from openai import OpenAI
from commonkit.minio.minio_service import MinioService
from commonkit.utilities.datetime_utilities import DatetimeUtilities
client = OpenAI()
def start_conversation(conversation_id: str, first_message: str, model: str):
first_chat=[{"role": "user", "content": first_message}]
if model:
model = model
stream = client.responses.create(
model= model, # Or another supported model
input= first_chat,
tools=[
# {
# "type": "code_interpreter",
# "container": {"type": "auto", "file_ids": [initial_file_id]} # Optional: if using a file
# }
],
stream=True
) # type: ignore
# history.append({"role": "assistant", "content": resp.output_text})
for event in stream:
print(event)
# return resp.output_text
# start_conversation("", "viết 1 bài văn 100 từ", "gpt-4.1" )
# for model in client.models.list():
# print(model)
def create_files():
minio_client = MinioService(host="http://192.168.1.241:9000",
access_key="khanhnq",
secret_key="Difi@2025",
bucket_name="difi",
is_secure=False)
# Lấy file từ MinIO
obj = minio_client.get_object("difi", "file/ffbcd49f-b0b0-4a19-b128-ac601c85b87e/nhn.xlsx")
if obj != None:
file = client.files.create(
file=io.BytesIO(obj.read()), # truyền buffer trực tiếp
purpose="user_data"
)
print(file.id)
def retrieve_files(file_id):
print(client.files.retrieve(file_id))
print(client.files.retrieve(file_id))
print(client.files.retrieve(file_id))
print(client.files.retrieve(file_id))
print(client.files.retrieve(file_id))
print(client.files.retrieve(file_id))
start_time = DatetimeUtilities.now()
retrieve_files("file-AYoxnnx1BmXBHTbqMYqh6N")
print((DatetimeUtilities.now()-start_time).total_seconds()/6)
\ No newline at end of file
from dto.check_sensitive_info_result_dto import CheckSensitiveInfoResultDTO
from openai import OpenAI
from typing import Callable, List, Literal, Optional, Sequence, TypedDict, Union
import re
import threading
import time
from commonkit.logging.logging_config import LogConfig
from commonkit.utilities.json_serializer import JSONSerializer
from dto.conversation_dto import ConversationDTO
from dto.create_conversation_name_result_dto import CreateConversationNameResultDTO
from enums.processing_state import ProcessingState
from enums.response_event_type import ResponseType
from enums.warning_result import WarningResult
class OpenAIHandler:
client: OpenAI
conversation_id: str
on_conversation_name_created: Callable[[dict], None]
def __init__(self, client: OpenAI, conversation_id: str):
log_config = LogConfig(__name__)
self.logger = log_config.logger
# log_config.remove_console_handler()
log_config.add_file_handler(
f"logs/log_openai_{conversation_id}.log")
self.client = client
self.conversation_id = conversation_id
# self.on_conversation_name_created = on_conversation_name_created
def get_conversation_name(self, first_user_message: str, on_conversation_name_created: Callable[[dict], None] ):
title = None
state = ProcessingState.IDLE
def worker(state, on_conversation_name_created: Callable[[dict], None]):
while True:
if state == ProcessingState.IDLE:
state = ProcessingState.PROCESSING
elif state == ProcessingState.PROCESSING:
try:
response = self.client.chat.completions.create(
model="gpt-4.1-2025-04-14",
messages=[
{
"role": "user",
"content": f"""
Bạn là AI đặt tiêu đề đa ngôn ngữ. Đọc tin nhắn đầu tiên của người dùng, xác định ngôn ngữ của tin nhắn đó và tạo 1 tiêu đề ngắn (2-5 từ), tự nhiên và phản ánh đúng bản chất/ý định bằng chính ngôn ngữ đó
nếu có chủ đề rõ ràng thì tóm gọn chủ đề bằng ngôn ngữ gốc,
nếu là chuỗi ngẫu nhiên/ký tự/emoji thì mô tả bản chất,
Nếu là phiên âm hoặc viết sai của một ngôn ngữ khác, hãy xác định và dùng từ gốc làm tiêu đề. Ví dụ: "a nhon xê ô" → "안녕하세요"; "bon rua" → "Bonjour"; "ni hảo" → "你好",
nếu là câu dở dang hay ẩn ý thì suy luận nội dung gần nhất,
còn nếu hoàn toàn mơ hồ thì dùng chính đầu vào làm tiêu đề.
Tin nhắn: "{first_user_message}"
"""
}
]
)
title = response.choices[0].message.content.strip()
state = ProcessingState.COMPLETED
except Exception as e:
self.logger.error(f"Lỗi khi gọi API: {e}", exc_info=True)
state = ProcessingState.ERROR
elif state == ProcessingState.COMPLETED:
self.logger.info(title)
create_conversation_name_result_dto = CreateConversationNameResultDTO()
create_conversation_name_result_dto.conversationName = title
create_conversation_name_result_dto.conversationId = self.conversation_id
on_conversation_name_created(CreateConversationNameResultDTO.to_dict(create_conversation_name_result_dto))
break
elif state == ProcessingState.ERROR:
self.logger.error("Lỗi khi gọi API")
break
else:
self.logger.error("Lỗi")
break
time.sleep(0.5)
t = threading.Thread(target=worker, args=[state, on_conversation_name_created], daemon=True)
t.start()
# t.join()
return title
def contains_sensitive_info(self,message: str, is_start: bool, chat_id: str ,on_contains_sensitive_info_checked: Callable[[dict], None]):
state = ProcessingState.IDLE
self.logger.info(chat_id)
def start(state, message, chat_id, on_contains_sensitive_info_checked):
while True:
if state == ProcessingState.IDLE:
self.logger.info("Idling")
state = ProcessingState.PROCESSING
elif state == ProcessingState.PROCESSING:
self.logger.info("start processing")
try:
# prompt = f"""
# Bạn là bộ lọc thông tin nhạy cảm (PII) và thông tin doanh nghiệp.
# Phân tích văn bản dưới đây và trả về {WarningResult.WARNING} nếu có bất kỳ thông tin nhạy cảm nào, {WarningResult.ACCEPTED} nếu không có.
# Chỉ trả {WarningResult.WARNING} hoặc {WarningResult.ACCEPTED}, KHÔNG giải thích gì thêm.
# Văn bản:
# {message}
# Các loại thông tin nhạy cảm cần kiểm tra:
# 1. Thông tin cá nhân:
# - Tên riêng (ít nhất 2 từ)
# - Email cá nhân
# - Số CCCD/CMND (9-12 chữ số)
# - Số điện thoại (VN: 10-11 chữ số)
# - Số hộ chiếu
# 2. Thông tin doanh nghiệp/đối tác:
# - Tên công ty/doanh nghiệp
# - Email liên hệ công ty
# - Số điện thoại liên hệ công ty
# """
prompt = f"""
Bạn là bộ lọc phát hiện thông tin nhạy cảm (PII và thông tin doanh nghiệp).
Nhiệm vụ: phân tích văn bản và trả về đúng một trong hai giá trị:
- {WarningResult.WARNING}: nếu có chứa bất kỳ thông tin nhạy cảm nào trong danh sách dưới đây.
- {WarningResult.ACCEPTED}: nếu không có.
Yêu cầu bắt buộc:
- Chỉ trả về {WarningResult.WARNING} hoặc {WarningResult.ACCEPTED}, không thêm giải thích hoặc ký tự khác.
- Chỉ xét các loại thông tin được liệt kê, không suy diễn ngoài phạm vi.
Danh mục thông tin nhạy cảm cần kiểm tra:
1. Thông tin cá nhân:
- Họ và tên đầy đủ (ít nhất 2 từ, viết hoa chữ cái đầu).
- Email cá nhân (dạng tên@miền).
- Số CCCD/CMND (9-12 chữ số liên tục).
- Số điện thoại cá nhân Việt Nam (bắt đầu bằng 0, dài 10-11 chữ số).
- Số hộ chiếu (theo định dạng phổ biến tại Việt Nam, 8 ký tự gồm chữ và số).
2. Thông tin doanh nghiệp / đối tác:
- Tên công ty, tổ chức, doanh nghiệp (ít nhất 2 từ, có chữ viết hoa).
- Email liên hệ công ty (dạng tên@tencongty...).
- Số điện thoại công ty (theo định dạng số điện thoại Việt Nam).
Văn bản cần kiểm tra:
{message}
"""
response = self.client.chat.completions.create(
model="gpt-4.1-mini-2025-04-14",
messages=[
{"role": "system", "content": "Bạn là bộ lọc thông tin nhạy cảm."},
{"role": "user", "content": prompt}
],
temperature=0
)
result = response.choices[0].message.content.strip()
self.logger.info(result)
state = ProcessingState.COMPLETED
except Exception as e:
self.logger.error(e , exc_info=True)
return
elif state == ProcessingState.COMPLETED:
check_sensitive_info_result_dto = CheckSensitiveInfoResultDTO()
check_sensitive_info_result_dto.conversationId = self.conversation_id
check_sensitive_info_result_dto.sensitiveInfoResult = result
check_sensitive_info_result_dto.message = message
check_sensitive_info_result_dto.chatId = chat_id
check_sensitive_info_result_dto.isStart = is_start
on_contains_sensitive_info_checked(CheckSensitiveInfoResultDTO.to_dict(check_sensitive_info_result_dto))
break
elif state == ProcessingState.ERROR:
self.logger.error("state == ProcessingState.ERROR", exc_info=True)
break
else:
self.logger.error("state == NULL", exc_info=True)
break
time.sleep(0.5)
t = threading.Thread(target=start,args=[state, message, chat_id, on_contains_sensitive_info_checked,], daemon=True)
t.start()
# t.join()
return
def validate_user_message(self, user_message: str, conversation_id: str):
pass
def on_validated_message(self, conversation_id: str):
pass
def evaluate_user_message(self, user_conversation: ConversationDTO):
pass
def on_evaluated_user_message(self, conversation_id: str):
pass
def chat(self, chat_id: str, input, model: str, on_response_callback: Callable[[str, str, str, str], None]):
if model:
self.model = model
stream = self.client.responses.create(
model= model,
input= input,
# tools=[{
# "type": "code_interpreter",
# "container": {"type": "auto", "file_ids": [initial_file_id]} # Optional: if using a file
# }],
stream=True
) # type: ignore
for event in stream:
if event.type == "response.output_text.delta":
on_response_callback(self.conversation_id, chat_id, event.delta, ResponseType.CONTENT)
if event.type == "response.output_text.done":
on_response_callback(self.conversation_id, chat_id, event.text, ResponseType.DONE)
# def file_handler(self, url: str):
# file = self.client.files.create(
# file=("draconomicon.pdf", response.content), # tên file + binary data
# purpose="user_data"
# )
# return file.id
\ No newline at end of file
import threading
from typing import Dict, List
from commonkit.logging.logging_config import LogConfig
from dto.chat_input_dto import ChatInputDTO
from dto.chat_dto import ChatDTO
from dto.chat_response_dto import ChatResponseDTO
from dto.check_sensitive_info_result_dto import CheckSensitiveInfoResultDTO
from enums.ai_message_type import AIMessageType
from openai import OpenAI
import json
import schedule
import time
from ai_service.openai_handler import OpenAIHandler
from commonkit.rabbitmq.rabbitmq_producer import RabbitMQProducer
from commonkit.utilities.json_serializer import JSONSerializer
from config.config import Config
from dto.ai_service_message_dto import AIServiceMessageDTO
from dto.create_conversation_name_result_dto import CreateConversationNameResultDTO
from enums.content_types import ContentTypes
from enums.input_role import InputRoles
from enums.warning_result import WarningResult
log_config = LogConfig(__name__)
logger = log_config.logger
class OpenAIServiceManagement():
openai_dict: Dict[str, OpenAIHandler]
openai_client: OpenAI
create_name_passing_cases:set[str] = set()
company_info: set[str] = set()
def __init__(self, openai_client: OpenAI) -> None:
self.openai_dict = {}
self.openai_client = openai_client
self.create_conversation_name_producer = RabbitMQProducer(host=Config.rbmq_host, port=Config.rbmq_port, virtual_host=Config.rbmq_virtual_host,
queue_name="create_conversation_name_result", exchange=f"", username=Config.rbmq_username, password=Config.rbmq_password)
self.create_conversation_name_producer.start()
self.contains_sensitive_info_producer = RabbitMQProducer(host=Config.rbmq_host, port=Config.rbmq_port, virtual_host=Config.rbmq_virtual_host,
queue_name="contains_sensitive_info_result", exchange=f"", username=Config.rbmq_username, password=Config.rbmq_password)
self.contains_sensitive_info_producer.start()
self.start_daily_job("00:00")
self.chat_response_producer = RabbitMQProducer(host=Config.rbmq_host, port=Config.rbmq_port, virtual_host=Config.rbmq_virtual_host,
queue_name="chat_response", exchange=f"", username=Config.rbmq_username, password=Config.rbmq_password)
self.chat_response_producer.start()
def read_file_exception(self,file_path: str,arr:set[str]):
try:
with open(file_path, "r", encoding="utf-8") as f:
data = json.load(f)
new_arr = {phrase for phrases in data.values() for phrase in phrases}
arr |= new_arr
except Exception as e:
print(f" Error read file: {e}")
def start_daily_job(self, time_str: str = "00:00"):
# chạy ngay lần đầu tiên
self.read_file_exception("./resource/create_name_passing_cases.json",self.create_name_passing_cases)
self.read_file_exception("./resource/company_info.json",self.company_info)
# schedule để chạy lại hằng ngày
schedule.every(1).day.at(time_str).do(self.read_file_exception,"./resource/create_name_passing_cases.json",self.create_name_passing_cases)
schedule.every(1).day.at(time_str).do(self.read_file_exception,"./resource/company_info.json",self.company_info)
def run_pending():
while True:
schedule.run_pending()
time.sleep(30)
t = threading.Thread(target=run_pending, daemon=True)
t.start()
# t.join()
def get_conversation_name(self, ai_service_message_dto: AIServiceMessageDTO):
conversation_id = ai_service_message_dto.conversationId
first_message = ai_service_message_dto.firstMessage
for create_name_passing_case in self.create_name_passing_cases:
if first_message.lower() == create_name_passing_case.lower():
create_conversation_name_result_dto = CreateConversationNameResultDTO()
create_conversation_name_result_dto.conversationName = "New Chat"
create_conversation_name_result_dto.conversationId = conversation_id
self.on_conversation_name_created(CreateConversationNameResultDTO.to_dict(create_conversation_name_result_dto))
return
if conversation_id not in self.openai_dict:
self.openai_dict[conversation_id] = OpenAIHandler(client=self.openai_client, conversation_id=conversation_id,)
self.openai_dict[conversation_id].get_conversation_name(first_user_message=first_message, on_conversation_name_created=self.on_conversation_name_created)
def on_conversation_name_created(self, create_conversation_name_result_dto: dict):
rbmq_message_dict = {
"event": AIMessageType.CREATE_NAME,
"data": create_conversation_name_result_dto
}
rbmq_message_str = JSONSerializer.serialize_json_dic(
dic=rbmq_message_dict)
self.create_conversation_name_producer.publish(body=rbmq_message_str)
def check_contains_sensitive_info(self,ai_service_message_dto: AIServiceMessageDTO):
conversation_id = ai_service_message_dto.conversationId
message = ai_service_message_dto.message
chat_id = ai_service_message_dto.chatId
is_start = bool(ai_service_message_dto.firstMessage!="")
for info in self.company_info:
if info.lower() in message.lower():
check_sensitive_info_result_dto = CheckSensitiveInfoResultDTO()
check_sensitive_info_result_dto.conversationId = conversation_id
check_sensitive_info_result_dto.sensitiveInfoResult = WarningResult.WARNING
check_sensitive_info_result_dto.message = message
check_sensitive_info_result_dto.chatId = chat_id
check_sensitive_info_result_dto.isStart = is_start
self.on_contains_sensitive_info_checked(CheckSensitiveInfoResultDTO.to_dict(check_sensitive_info_result_dto))
return
if conversation_id not in self.openai_dict:
self.openai_dict[conversation_id] = OpenAIHandler(client=self.openai_client, conversation_id=conversation_id)
self.openai_dict[conversation_id].contains_sensitive_info(message=message, is_start=is_start, chat_id=chat_id, on_contains_sensitive_info_checked=self.on_contains_sensitive_info_checked)
def on_contains_sensitive_info_checked(self, check_contains_sensitive_info_result_dto: dict):
rbmq_message_dict = {
"event": AIMessageType.VALIDATE_MESSAGE,
"data": check_contains_sensitive_info_result_dto
}
rbmq_message_str = JSONSerializer.serialize_json_dic(
dic=rbmq_message_dict)
self.contains_sensitive_info_producer.publish(body=rbmq_message_str)
def chat(self, chat_input_dto: ChatInputDTO):
conversation_id = chat_input_dto.conversationId
input = []
spread_sheet_urls = []
other_file_urls = []
if chat_input_dto.developerMessage != None and chat_input_dto.developerMessage != "":
input.append({
"role": InputRoles.SYSTEM,
"content": [{"type": ContentTypes.INPUT_TEXT, "text":chat_input_dto.developerMessage}]
})
for chat_dto in chat_input_dto.chatDTOs:
user_contents = []
user_content_text = {
"type": ContentTypes.INPUT_TEXT,
"text": chat_dto.question
}
user_contents.append(user_content_text)
if chat_dto.imageFileUrls != [] and chat_dto.imageFileUrls != None:
for url in chat_dto.imageFileUrls:
if "/difi/image" in url:
user_content_image = {
"type": ContentTypes.INPUT_IMAGE,
"text": url
}
user_contents.append(user_content_image)
elif "/difi/file" in url:
if url.endswith(".pdf"):
user_content_file = {
"type": ContentTypes.INPUT_FILE,
"text": url
}
user_contents.append(user_content_file)
elif url.endswith(".xlsx") or url.endswith(".xls") or url.endswith(".csv"):
spread_sheet_urls.append(url)
else:
other_file_urls.append(url)
input.append({
"role": InputRoles.USER,
"content": user_contents
})
if chat_dto.response != None and chat_dto.response != "":
assistant_contents = []
assistant_content_text = {
"type": ContentTypes.OUTPUT_TEXT,
"text": chat_dto.response
}
assistant_contents.append(assistant_content_text)
input.append({
"role": InputRoles.ASSISTANT,
"content": assistant_contents
})
if conversation_id not in self.openai_dict:
self.openai_dict[conversation_id] = OpenAIHandler(client=self.openai_client, conversation_id=conversation_id)
self.openai_dict[conversation_id].chat(chat_id=chat_input_dto.chatId,
input=input,
model=chat_input_dto.model,
on_response_callback=self.on_response_callback)
def on_response_callback(self, conversation_id: str, chat_id: str, text: str, event_type: str):
chat_response_dto = ChatResponseDTO()
chat_response_dto.conversationId = conversation_id
chat_response_dto.chatId = chat_id
chat_response_dto.text = text
chat_response_dto.eventType = event_type
logger.info(chat_response_dto)
rbmq_message_dict = {
"event": AIMessageType.CHAT,
"data": chat_response_dto.to_dict()
}
rbmq_message_str = JSONSerializer.serialize_json_dic(
dic=rbmq_message_dict)
self.chat_response_producer.publish(body=rbmq_message_str)
\ No newline at end of file
Subproject commit d9df765221b8433690f89634a1e8f5c70f712471
import os
import threading
from commonkit.logging.logging_config import LogConfig
log_config = LogConfig(__name__)
logger = log_config.logger
class ConfigMeta(type):
_instances = {}
_lock = threading.Lock() # Đảm bảo thread-safe
def __call__(cls, *args, **kwargs):
with cls._lock:
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]
class BaseConfig(metaclass=ConfigMeta):
minio_host: str = None
minio_access_key: str = None
minio_secret_key: str = None
minio_bucket: str = None
minio_secure: bool = None
minio_domain: str = None
rbmq_username: str = None
rbmq_password: str = None
rbmq_host: str = None
rbmq_port: int = None
rbmq_virtual_host: str = None
rbmq_queue_prefix: str = None
rbmq_queue_postfix: str = None
recording_update_queue_name: str = None
def __init__(self):
#Minio
if "MINIO_HOST" in os.environ:
self.MINIO_HOST = os.environ["MINIO_HOST"].replace(
"https://", "").replace("http://", "")
self.MINIO_SSL_ENABLE = "https" in os.environ["MINIO_HOST"]
if "MINIO_ACCESS_KEY" in os.environ:
self.MINIO_ACCESS_KEY = os.environ["MINIO_ACCESS_KEY"]
if "MINIO_SECRET_KEY" in os.environ:
self.MINIO_SECRET_KEY = os.environ["MINIO_SECRET_KEY"]
if "MINIO_PART_SIZE" in os.environ:
self.MINIO_PART_SIZE = os.environ["MINIO_PART_SIZE"]
if "MINIO_DOMAIN" in os.environ:
self.MINIO_DOMAIN = os.environ["MINIO_DOMAIN"]
if "MINIO_DEFAULT_BUCKETS" in os.environ:
self.MINIO_DEFAULT_BUCKETS = os.environ["MINIO_DEFAULT_BUCKETS"]
# RabbitMQ
if "RABBITMQ_HOST" in os.environ:
self.rbmq_host = os.environ["RABBITMQ_HOST"]
if "RABBITMQ_PORT" in os.environ:
self.rbmq_port = int(os.environ["RABBITMQ_PORT"])
if "RABBITMQ_VIRTUAL_HOST" in os.environ:
self.rbmq_virtual_host = os.environ["RABBITMQ_VIRTUAL_HOST"]
if "RABBITMQ_USERNAME" in os.environ:
self.rbmq_username = os.environ["RABBITMQ_USERNAME"]
if "RABBITMQ_PASSWORD" in os.environ:
self.rbmq_password = os.environ["RABBITMQ_PASSWORD"]
print(self.rbmq_host)
Config = BaseConfig()
from dataclasses import dataclass
from commonkit.sqlalchemy.base_dto import BaseDTO
@dataclass
class AIServiceMessageDTO(BaseDTO):
conversationId: str = None
firstMessage: str = None
message: str = None
chatId: str = None
\ No newline at end of file
from dataclasses import dataclass
from typing import List
from commonkit.sqlalchemy.base_dto import BaseDTO
@dataclass
class ChatDTO(BaseDTO):
question: str = None
response: str = None
model: str = None
imageFileUrls: List[str] = None
from dataclasses import dataclass
from typing import List
from commonkit.sqlalchemy.base_dto import BaseDTO
from dto.chat_dto import ChatDTO
@dataclass
class ChatInputDTO(BaseDTO):
conversationId: str = None
chatDTOs: List[ChatDTO] = None
model: str = None
chatId: str = None
developerMessage: str = None
@classmethod
def from_dict(cls, data: dict):
dto = super().from_dict(data)
if data.get("chatDTOs") is not None or data.get("chatDTOs") != []:
dto.chatDTOs = []
for chat_dto in data.get("chatDTOs"):
dto.chatDTOs.append(ChatDTO.from_dict(chat_dto))
return dto
\ No newline at end of file
from dataclasses import dataclass
from commonkit.sqlalchemy.base_dto import BaseDTO
@dataclass
class ChatResponseDTO(BaseDTO):
text: str = None
conversationId: str = None
chatId: str = None
eventType: str = None
\ No newline at end of file
from dataclasses import dataclass
from commonkit.sqlalchemy.base_dto import BaseDTO
@dataclass
class CheckSensitiveInfoResultDTO(BaseDTO):
sensitiveInfoResult: str = None
conversationId: str = None
message: str = None
chatId: str = None
isStart: bool = None
\ No newline at end of file
from dataclasses import dataclass
from typing import List
from commonkit.sqlalchemy.base_dto import BaseDTO
from dto.chat_dto import ChatDTO
@dataclass
class ConversationDTO(BaseDTO):
name: str = None
chatDTOs: List[ChatDTO] = None
initModel: str = None
isCompleted: bool = None
\ No newline at end of file
from dataclasses import dataclass
from commonkit.sqlalchemy.base_dto import BaseDTO
@dataclass
class CreateConversationNameResultDTO(BaseDTO):
conversationName: str = None
conversationId: str = None
\ No newline at end of file
class AIMessageType:
CREATE_NAME = "CREATE_NAME"
VALIDATE_MESSAGE = "VALIDATE_MESSAGE"
CHAT = "CHAT"
\ No newline at end of file
class ContentTypes:
INPUT_TEXT = "input_text"
INPUT_IMAGE = "input_image"
INPUT_FILE = "input_file"
OUTPUT_TEXT = "output_text"
\ No newline at end of file
class InputRoles:
USER = "user"
ASSISTANT = "assistant"
SYSTEM = "system"
\ No newline at end of file
class ProcessingState:
IDLE="IDLE"
PROCESSING="PROCESSING"
COMPLETED="COMPLETED"
ERROR="ERROR"
\ No newline at end of file
class ResponseType:
CONTENT = "CONTENT"
NAME = "NAME"
DONE = "DONE"
WARNING = "WARNING"
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment