cwyodmodules 0.3.31__tar.gz → 0.3.33__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/PKG-INFO +2 -1
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/api/chat_history.py +14 -7
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/chat_history/auth_utils.py +7 -3
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/chat_history/cosmosdb.py +17 -1
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/chat_history/postgresdbservice.py +291 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/common/source_document.py +60 -61
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/fixed_size_overlap.py +8 -3
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/layout.py +8 -3
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/page.py +8 -3
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/document_loading/read.py +44 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/azure_computer_vision_client.py +10 -3
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/azure_form_recognizer_helper.py +6 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/azure_identity_helper.py +3 -34
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/azure_postgres_helper.py +14 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/azure_postgres_helper_light_rag.py +14 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/azure_search_helper.py +15 -6
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/config_helper.py +24 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/env_helper.py +9 -9
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/lightrag_helper.py +9 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/llm_helper.py +13 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/secret_helper.py +9 -9
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/integrated_vectorization/azure_search_index.py +8 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/integrated_vectorization/azure_search_indexer.py +9 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/integrated_vectorization/azure_search_skillset.py +6 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/orchestrator/lang_chain_agent.py +8 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/orchestrator/open_ai_functions.py +6 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/orchestrator/orchestrator_base.py +9 -3
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/orchestrator/prompt_flow.py +8 -2
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/orchestrator/semantic_kernel_orchestrator.py +196 -0
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/parser/output_parser_tool.py +151 -0
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/plugins/outlook_calendar_plugin.py +119 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/search/azure_search_handler.py +16 -3
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/search/azure_search_handler_light_rag.py +14 -2
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/search/integrated_vectorization_search_handler.py +36 -24
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/search/lightrag_search_handler.py +14 -2
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/search/postgres_search_handler.py +142 -0
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/search/postgres_search_handler_light_rag.py +146 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/search/search.py +21 -24
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/tools/content_safety_checker.py +91 -0
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/tools/post_prompt_tool.py +64 -0
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/tools/question_answer_tool.py +333 -0
- cwyodmodules-0.3.33/cwyodmodules/batch/utilities/tools/text_processing_tool.py +50 -0
- cwyodmodules-0.3.33/cwyodmodules/logging_config.py +15 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules.egg-info/PKG-INFO +2 -1
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules.egg-info/SOURCES.txt +1 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules.egg-info/requires.txt +1 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/pyproject.toml +3 -2
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/chat_history/postgresdbservice.py +0 -306
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/document_loading/read.py +0 -48
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/orchestrator/semantic_kernel_orchestrator.py +0 -199
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/parser/output_parser_tool.py +0 -151
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/plugins/outlook_calendar_plugin.py +0 -121
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/search/postgres_search_handler.py +0 -139
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/search/postgres_search_handler_light_rag.py +0 -147
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/tools/content_safety_checker.py +0 -103
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/tools/post_prompt_tool.py +0 -76
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/tools/question_answer_tool.py +0 -343
- cwyodmodules-0.3.31/cwyodmodules/batch/utilities/tools/text_processing_tool.py +0 -53
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/LICENSE +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/README.md +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/api/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/chat_history/database_client_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/chat_history/database_factory.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/chat_history/sample_user.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/common/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/common/answer.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/chunking_strategy.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/document_chunking_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/paragraph.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_chunking/strategies.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_loading/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_loading/document_loading_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_loading/layout.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_loading/strategies.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_loading/web.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/document_loading/word_document.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/azure_blob_storage_client.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/assistant_strategy.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/conversation_flow.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/database_type.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/default.json +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/default_contract_assistant_prompt.txt +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/default_employee_assistant_prompt.txt +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/config/embedding_config.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/document_chunking_helper.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/document_loading_helper.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/embedders/embedder_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/embedders/embedder_factory.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/embedders/integrated_vectorization_embedder.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/embedders/postgres_embedder.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/embedders/push_embedder.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/helpers/orchestrator_helper.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/integrated_vectorization/azure_search_datasource.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/loggers/conversation_logger.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/orchestrator/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/orchestrator/orchestration_strategy.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/orchestrator/strategies.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/parser/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/parser/parser_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/plugins/chat_plugin.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/plugins/post_answering_plugin.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/search/search_handler_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/tools/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/tools/answer_processing_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/tools/answering_tool_base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/config.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/database/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/database/base.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/database/models.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/indexing/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/indexing/chunking.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/indexing/extraction.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/indexing/types.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/indexing/upsert.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/indexing/utils.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/llm/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/llm/llm.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/llm/prompt.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/main.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/query/__init__.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/query/generate.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/query/graph_search.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/query/types.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/graphrag/query/vector_search.py +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules.egg-info/dependency_links.txt +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules.egg-info/top_level.txt +0 -0
- {cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cwyodmodules
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.33
|
4
4
|
Summary: Add your description here
|
5
5
|
Author-email: Patrik <patrikhartl@gmail.com>
|
6
6
|
Classifier: Operating System :: OS Independent
|
@@ -40,6 +40,7 @@ Requires-Dist: azure-search-documents==11.6.0b4
|
|
40
40
|
Requires-Dist: semantic-kernel==1.3.0
|
41
41
|
Requires-Dist: pydantic==2.7.4
|
42
42
|
Requires-Dist: pandas>=2.2.3
|
43
|
+
Requires-Dist: azpaddypy>=0.2.4
|
43
44
|
Dynamic: license-file
|
44
45
|
|
45
46
|
# paddypy
|
@@ -1,5 +1,4 @@
|
|
1
1
|
import os
|
2
|
-
import logging
|
3
2
|
from uuid import uuid4
|
4
3
|
|
5
4
|
# from dotenv import load_dotenv
|
@@ -11,15 +10,16 @@ from ..batch.utilities.chat_history.auth_utils import (
|
|
11
10
|
from ..batch.utilities.helpers.config.config_helper import ConfigHelper
|
12
11
|
from ..batch.utilities.helpers.env_helper import EnvHelper
|
13
12
|
from ..batch.utilities.chat_history.database_factory import DatabaseFactory
|
14
|
-
|
13
|
+
from logging_config import logger
|
15
14
|
# load_dotenv()
|
15
|
+
|
16
16
|
bp_chat_history_response = Blueprint("chat_history", __name__)
|
17
|
-
logger = logging.getLogger("__main__")
|
18
|
-
logger.setLevel(level=os.environ.get("LOGLEVEL", "INFO").upper())
|
19
17
|
|
20
18
|
env_helper: EnvHelper = EnvHelper()
|
19
|
+
log_args = env_helper.LOG_ARGS
|
20
|
+
log_result = env_helper.LOG_RESULT
|
21
21
|
|
22
|
-
|
22
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
23
23
|
def init_database_client():
|
24
24
|
try:
|
25
25
|
conversation_client = DatabaseFactory.get_conversation_client()
|
@@ -28,7 +28,7 @@ def init_database_client():
|
|
28
28
|
logger.exception("Exception in database initialization: %s", e)
|
29
29
|
raise e
|
30
30
|
|
31
|
-
|
31
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
32
32
|
def init_openai_client():
|
33
33
|
try:
|
34
34
|
if env_helper.is_auth_type_keys():
|
@@ -45,11 +45,12 @@ def init_openai_client():
|
|
45
45
|
)
|
46
46
|
return azure_openai_client
|
47
47
|
except Exception as e:
|
48
|
-
|
48
|
+
logger.exception("Exception in Azure OpenAI initialization: %s", e)
|
49
49
|
raise e
|
50
50
|
|
51
51
|
|
52
52
|
@bp_chat_history_response.route("/history/list", methods=["GET"])
|
53
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
53
54
|
async def list_conversations():
|
54
55
|
config = ConfigHelper.get_active_config_or_default()
|
55
56
|
if not config.enable_chat_history:
|
@@ -89,6 +90,7 @@ async def list_conversations():
|
|
89
90
|
|
90
91
|
|
91
92
|
@bp_chat_history_response.route("/history/rename", methods=["POST"])
|
93
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
92
94
|
async def rename_conversation():
|
93
95
|
config = ConfigHelper.get_active_config_or_default()
|
94
96
|
if not config.enable_chat_history:
|
@@ -151,6 +153,7 @@ async def rename_conversation():
|
|
151
153
|
|
152
154
|
|
153
155
|
@bp_chat_history_response.route("/history/read", methods=["POST"])
|
156
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
154
157
|
async def get_conversation():
|
155
158
|
config = ConfigHelper.get_active_config_or_default()
|
156
159
|
if not config.enable_chat_history:
|
@@ -223,6 +226,7 @@ async def get_conversation():
|
|
223
226
|
|
224
227
|
|
225
228
|
@bp_chat_history_response.route("/history/delete", methods=["DELETE"])
|
229
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
226
230
|
async def delete_conversation():
|
227
231
|
config = ConfigHelper.get_active_config_or_default()
|
228
232
|
if not config.enable_chat_history:
|
@@ -283,6 +287,7 @@ async def delete_conversation():
|
|
283
287
|
|
284
288
|
|
285
289
|
@bp_chat_history_response.route("/history/delete_all", methods=["DELETE"])
|
290
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
286
291
|
async def delete_all_conversations():
|
287
292
|
config = ConfigHelper.get_active_config_or_default()
|
288
293
|
|
@@ -354,6 +359,7 @@ async def delete_all_conversations():
|
|
354
359
|
|
355
360
|
|
356
361
|
@bp_chat_history_response.route("/history/update", methods=["POST"])
|
362
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
357
363
|
async def update_conversation():
|
358
364
|
config = ConfigHelper.get_active_config_or_default()
|
359
365
|
if not config.enable_chat_history:
|
@@ -455,6 +461,7 @@ async def update_conversation():
|
|
455
461
|
|
456
462
|
|
457
463
|
@bp_chat_history_response.route("/history/frontend_settings", methods=["GET"])
|
464
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
458
465
|
def get_frontend_settings():
|
459
466
|
try:
|
460
467
|
# Clear the cache for the config helper method
|
{cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/chat_history/auth_utils.py
RENAMED
@@ -1,8 +1,13 @@
|
|
1
1
|
import base64
|
2
2
|
import json
|
3
|
-
import logging
|
4
3
|
|
4
|
+
from ...utilities.helpers.env_helper import EnvHelper
|
5
|
+
from logging_config import logger
|
6
|
+
env_helper: EnvHelper = EnvHelper()
|
7
|
+
log_args = env_helper.LOG_ARGS
|
8
|
+
log_result = env_helper.LOG_RESULT
|
5
9
|
|
10
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
6
11
|
def get_authenticated_user_details(request_headers):
|
7
12
|
user_object = {}
|
8
13
|
|
@@ -25,9 +30,8 @@ def get_authenticated_user_details(request_headers):
|
|
25
30
|
|
26
31
|
return user_object
|
27
32
|
|
28
|
-
|
33
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
29
34
|
def get_tenantid(client_principal_b64):
|
30
|
-
logger = logging.getLogger("__main__")
|
31
35
|
tenant_id = ""
|
32
36
|
if client_principal_b64:
|
33
37
|
try:
|
{cwyodmodules-0.3.31 → cwyodmodules-0.3.33}/cwyodmodules/batch/utilities/chat_history/cosmosdb.py
RENAMED
@@ -3,7 +3,11 @@ from azure.cosmos.aio import CosmosClient
|
|
3
3
|
from azure.cosmos import exceptions
|
4
4
|
|
5
5
|
from .database_client_base import DatabaseClientBase
|
6
|
-
|
6
|
+
from ...utilities.helpers.env_helper import EnvHelper
|
7
|
+
from logging_config import logger
|
8
|
+
env_helper: EnvHelper = EnvHelper()
|
9
|
+
log_args = env_helper.LOG_ARGS
|
10
|
+
log_result = env_helper.LOG_RESULT
|
7
11
|
|
8
12
|
class CosmosConversationClient(DatabaseClientBase):
|
9
13
|
|
@@ -44,12 +48,15 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
44
48
|
except exceptions.CosmosResourceNotFoundError:
|
45
49
|
raise ValueError("Invalid CosmosDB container name")
|
46
50
|
|
51
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
47
52
|
async def connect(self):
|
48
53
|
pass
|
49
54
|
|
55
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
50
56
|
async def close(self):
|
51
57
|
pass
|
52
58
|
|
59
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
53
60
|
async def ensure(self):
|
54
61
|
if (
|
55
62
|
not self.cosmosdb_client
|
@@ -72,6 +79,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
72
79
|
|
73
80
|
return True, "CosmosDB client initialized successfully"
|
74
81
|
|
82
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
75
83
|
async def create_conversation(self, user_id, conversation_id, title=""):
|
76
84
|
conversation = {
|
77
85
|
"id": conversation_id,
|
@@ -89,6 +97,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
89
97
|
else:
|
90
98
|
return False
|
91
99
|
|
100
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
92
101
|
async def upsert_conversation(self, conversation):
|
93
102
|
resp = await self.container_client.upsert_item(conversation)
|
94
103
|
if resp:
|
@@ -96,6 +105,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
96
105
|
else:
|
97
106
|
return False
|
98
107
|
|
108
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
99
109
|
async def delete_conversation(self, user_id, conversation_id):
|
100
110
|
conversation = await self.container_client.read_item(
|
101
111
|
item=conversation_id, partition_key=user_id
|
@@ -108,6 +118,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
108
118
|
else:
|
109
119
|
return True
|
110
120
|
|
121
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
111
122
|
async def delete_messages(self, conversation_id, user_id):
|
112
123
|
# get a list of all the messages in the conversation
|
113
124
|
messages = await self.get_messages(user_id, conversation_id)
|
@@ -120,6 +131,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
120
131
|
response_list.append(resp)
|
121
132
|
return response_list
|
122
133
|
|
134
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
123
135
|
async def get_conversations(self, user_id, limit, sort_order="DESC", offset=0):
|
124
136
|
parameters = [{"name": "@userId", "value": user_id}]
|
125
137
|
query = f"SELECT * FROM c where c.userId = @userId and c.type='conversation' order by c.updatedAt {sort_order}"
|
@@ -134,6 +146,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
134
146
|
|
135
147
|
return conversations
|
136
148
|
|
149
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
137
150
|
async def get_conversation(self, user_id, conversation_id):
|
138
151
|
parameters = [
|
139
152
|
{"name": "@conversationId", "value": conversation_id},
|
@@ -152,6 +165,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
152
165
|
else:
|
153
166
|
return conversations[0]
|
154
167
|
|
168
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
155
169
|
async def create_message(self, uuid, conversation_id, user_id, input_message: dict):
|
156
170
|
message = {
|
157
171
|
"id": uuid,
|
@@ -179,6 +193,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
179
193
|
else:
|
180
194
|
return False
|
181
195
|
|
196
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
182
197
|
async def update_message_feedback(self, user_id, message_id, feedback):
|
183
198
|
message = await self.container_client.read_item(
|
184
199
|
item=message_id, partition_key=user_id
|
@@ -190,6 +205,7 @@ class CosmosConversationClient(DatabaseClientBase):
|
|
190
205
|
else:
|
191
206
|
return False
|
192
207
|
|
208
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
193
209
|
async def get_messages(self, user_id, conversation_id):
|
194
210
|
parameters = [
|
195
211
|
{"name": "@conversationId", "value": conversation_id},
|
@@ -0,0 +1,291 @@
|
|
1
|
+
import asyncpg
|
2
|
+
from datetime import datetime, timezone
|
3
|
+
from ..helpers.azure_identity_helper import AzureIdentityHelper
|
4
|
+
from .database_client_base import DatabaseClientBase
|
5
|
+
|
6
|
+
from ...utilities.helpers.env_helper import EnvHelper
|
7
|
+
from logging_config import logger
|
8
|
+
env_helper: EnvHelper = EnvHelper()
|
9
|
+
log_args = env_helper.LOG_ARGS
|
10
|
+
log_result = env_helper.LOG_RESULT
|
11
|
+
|
12
|
+
|
13
|
+
class PostgresConversationClient(DatabaseClientBase):
|
14
|
+
|
15
|
+
def __init__(
|
16
|
+
self, user: str, host: str, database: str, enable_message_feedback: bool = False
|
17
|
+
):
|
18
|
+
self.azure_identity_helper = AzureIdentityHelper()
|
19
|
+
self.user = user
|
20
|
+
self.host = host
|
21
|
+
self.database = database
|
22
|
+
self.enable_message_feedback = enable_message_feedback
|
23
|
+
self.conn = None
|
24
|
+
|
25
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
26
|
+
async def connect(self):
|
27
|
+
try:
|
28
|
+
access_information = self.azure_identity_helper.get_token(scopes="https://ossrdbms-aad.database.windows.net/.default")
|
29
|
+
token = access_information.token
|
30
|
+
self.conn = await asyncpg.connect(
|
31
|
+
user=self.user,
|
32
|
+
host=self.host,
|
33
|
+
database=self.database,
|
34
|
+
password=token,
|
35
|
+
port=5432,
|
36
|
+
ssl="require",
|
37
|
+
)
|
38
|
+
logger.info("Successfully connected to PostgreSQL")
|
39
|
+
except Exception as e:
|
40
|
+
logger.error("Failed to connect to PostgreSQL: %s", e, exc_info=True)
|
41
|
+
raise
|
42
|
+
|
43
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
44
|
+
async def close(self):
|
45
|
+
if self.conn:
|
46
|
+
await self.conn.close()
|
47
|
+
logger.info("PostgreSQL connection closed")
|
48
|
+
|
49
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
50
|
+
async def ensure(self):
|
51
|
+
if not self.conn:
|
52
|
+
logger.warning("PostgreSQL client not initialized correctly")
|
53
|
+
return False, "PostgreSQL client not initialized correctly"
|
54
|
+
logger.info("PostgreSQL client initialized successfully")
|
55
|
+
return True, "PostgreSQL client initialized successfully"
|
56
|
+
|
57
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
58
|
+
async def create_conversation(self, conversation_id, user_id, title=""):
|
59
|
+
utc_now = datetime.now(timezone.utc)
|
60
|
+
createdAt = utc_now.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
|
61
|
+
query = """
|
62
|
+
INSERT INTO conversations (id, conversation_id, type, "createdAt", "updatedAt", user_id, title)
|
63
|
+
VALUES ($1, $2, 'conversation', $3, $3, $4, $5)
|
64
|
+
RETURNING *
|
65
|
+
"""
|
66
|
+
try:
|
67
|
+
conversation = await self.conn.fetchrow(
|
68
|
+
query, conversation_id, conversation_id, createdAt, user_id, title
|
69
|
+
)
|
70
|
+
if conversation:
|
71
|
+
logger.info(f"Conversation created with id: {conversation_id}")
|
72
|
+
return dict(conversation)
|
73
|
+
else:
|
74
|
+
logger.warning(
|
75
|
+
f"Failed to create conversation with id: {conversation_id}"
|
76
|
+
)
|
77
|
+
return False
|
78
|
+
except Exception as e:
|
79
|
+
logger.error(
|
80
|
+
f"Error creating conversation with id: {conversation_id}: {e}",
|
81
|
+
exc_info=True,
|
82
|
+
)
|
83
|
+
raise
|
84
|
+
|
85
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
86
|
+
async def upsert_conversation(self, conversation):
|
87
|
+
query = """
|
88
|
+
INSERT INTO conversations (id, conversation_id, type, "createdAt", "updatedAt", user_id, title)
|
89
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
90
|
+
ON CONFLICT (id) DO UPDATE SET
|
91
|
+
"updatedAt" = EXCLUDED."updatedAt",
|
92
|
+
title = EXCLUDED.title
|
93
|
+
RETURNING *
|
94
|
+
"""
|
95
|
+
try:
|
96
|
+
updated_conversation = await self.conn.fetchrow(
|
97
|
+
query,
|
98
|
+
conversation["id"],
|
99
|
+
conversation["conversation_id"],
|
100
|
+
conversation["type"],
|
101
|
+
conversation["createdAt"],
|
102
|
+
conversation["updatedAt"],
|
103
|
+
conversation["user_id"],
|
104
|
+
conversation["title"],
|
105
|
+
)
|
106
|
+
if updated_conversation:
|
107
|
+
logger.info(f"Conversation upserted with id: {conversation['id']}")
|
108
|
+
return dict(updated_conversation)
|
109
|
+
else:
|
110
|
+
logger.warning(
|
111
|
+
f"Failed to upsert conversation with id: {conversation['id']}"
|
112
|
+
)
|
113
|
+
return False
|
114
|
+
except Exception as e:
|
115
|
+
logger.error(
|
116
|
+
f"Error upserting conversation with id: {conversation['id']}: {e}",
|
117
|
+
exc_info=True,
|
118
|
+
)
|
119
|
+
raise
|
120
|
+
|
121
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
122
|
+
async def delete_conversation(self, user_id, conversation_id):
|
123
|
+
query = (
|
124
|
+
"DELETE FROM conversations WHERE conversation_id = $1 AND user_id = $2"
|
125
|
+
)
|
126
|
+
try:
|
127
|
+
await self.conn.execute(query, conversation_id, user_id)
|
128
|
+
logger.info(
|
129
|
+
f"Conversation deleted with conversation_id: {conversation_id} and user_id: {user_id}"
|
130
|
+
)
|
131
|
+
return True
|
132
|
+
except Exception as e:
|
133
|
+
logger.error(
|
134
|
+
f"Error deleting conversation with conversation_id: {conversation_id} and user_id: {user_id}: {e}",
|
135
|
+
exc_info=True,
|
136
|
+
)
|
137
|
+
raise
|
138
|
+
|
139
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
140
|
+
async def delete_messages(self, conversation_id, user_id):
|
141
|
+
query = "DELETE FROM messages WHERE conversation_id = $1 AND user_id = $2 RETURNING *"
|
142
|
+
try:
|
143
|
+
messages = await self.conn.fetch(query, conversation_id, user_id)
|
144
|
+
logger.info(
|
145
|
+
f"Messages deleted for conversation_id: {conversation_id} and user_id: {user_id}"
|
146
|
+
)
|
147
|
+
return [dict(message) for message in messages]
|
148
|
+
except Exception as e:
|
149
|
+
logger.error(
|
150
|
+
f"Error deleting messages for conversation_id: {conversation_id} and user_id: {user_id}: {e}",
|
151
|
+
exc_info=True,
|
152
|
+
)
|
153
|
+
raise
|
154
|
+
|
155
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
156
|
+
async def get_conversations(self, user_id, limit=None, sort_order="DESC", offset=0):
|
157
|
+
try:
|
158
|
+
offset = int(offset) # Ensure offset is an integer
|
159
|
+
except ValueError:
|
160
|
+
logger.error("Offset must be an integer.", exc_info=True)
|
161
|
+
raise ValueError("Offset must be an integer.")
|
162
|
+
# Base query without LIMIT and OFFSET
|
163
|
+
query = f"""
|
164
|
+
SELECT * FROM conversations
|
165
|
+
WHERE user_id = $1 AND type = 'conversation'
|
166
|
+
ORDER BY "updatedAt" {sort_order}
|
167
|
+
"""
|
168
|
+
# Append LIMIT and OFFSET to the query if limit is specified
|
169
|
+
if limit is not None:
|
170
|
+
try:
|
171
|
+
limit = int(limit) # Ensure limit is an integer
|
172
|
+
query += " LIMIT $2 OFFSET $3"
|
173
|
+
# Fetch records with LIMIT and OFFSET
|
174
|
+
conversations = await self.conn.fetch(query, user_id, limit, offset)
|
175
|
+
logger.info(
|
176
|
+
f"Retrieved conversations for user_id: {user_id} with limit: {limit} and offset: {offset}"
|
177
|
+
)
|
178
|
+
except ValueError:
|
179
|
+
logger.error("Limit must be an integer.", exc_info=True)
|
180
|
+
raise ValueError("Limit must be an integer.")
|
181
|
+
else:
|
182
|
+
# Fetch records without LIMIT and OFFSET
|
183
|
+
conversations = await self.conn.fetch(query, user_id)
|
184
|
+
logger.info(
|
185
|
+
f"Retrieved conversations for user_id: {user_id} without limit and offset"
|
186
|
+
)
|
187
|
+
return [dict(conversation) for conversation in conversations]
|
188
|
+
|
189
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
190
|
+
async def get_conversation(self, user_id, conversation_id):
|
191
|
+
query = "SELECT * FROM conversations WHERE id = $1 AND user_id = $2 AND type = 'conversation'"
|
192
|
+
try:
|
193
|
+
conversation = await self.conn.fetchrow(query, conversation_id, user_id)
|
194
|
+
if conversation:
|
195
|
+
logger.info(
|
196
|
+
f"Retrieved conversation with id: {conversation_id} and user_id: {user_id}"
|
197
|
+
)
|
198
|
+
return dict(conversation)
|
199
|
+
else:
|
200
|
+
logger.warning(
|
201
|
+
f"No conversation found with id: {conversation_id} and user_id: {user_id}"
|
202
|
+
)
|
203
|
+
return None
|
204
|
+
except Exception as e:
|
205
|
+
logger.error(
|
206
|
+
f"Error retrieving conversation with id: {conversation_id} and user_id: {user_id}: {e}",
|
207
|
+
exc_info=True,
|
208
|
+
)
|
209
|
+
raise
|
210
|
+
|
211
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
212
|
+
async def create_message(self, uuid, conversation_id, user_id, input_message: dict):
|
213
|
+
message_id = uuid
|
214
|
+
utc_now = datetime.now(timezone.utc)
|
215
|
+
createdAt = utc_now.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
|
216
|
+
query = """
|
217
|
+
INSERT INTO messages (id, type, "createdAt", "updatedAt", user_id, conversation_id, role, content, feedback)
|
218
|
+
VALUES ($1, 'message', $2, $2, $3, $4, $5, $6, $7)
|
219
|
+
RETURNING *
|
220
|
+
"""
|
221
|
+
feedback = "" if self.enable_message_feedback else None
|
222
|
+
try:
|
223
|
+
message = await self.conn.fetchrow(
|
224
|
+
query,
|
225
|
+
message_id,
|
226
|
+
createdAt,
|
227
|
+
user_id,
|
228
|
+
conversation_id,
|
229
|
+
input_message["role"],
|
230
|
+
input_message["content"],
|
231
|
+
feedback,
|
232
|
+
)
|
233
|
+
|
234
|
+
if message:
|
235
|
+
update_query = 'UPDATE conversations SET "updatedAt" = $1 WHERE id = $2 AND user_id = $3 RETURNING *'
|
236
|
+
await self.conn.execute(
|
237
|
+
update_query, createdAt, conversation_id, user_id
|
238
|
+
)
|
239
|
+
logger.info(
|
240
|
+
f"Message created with id: {message_id} in conversation: {conversation_id}"
|
241
|
+
)
|
242
|
+
return dict(message)
|
243
|
+
else:
|
244
|
+
logger.warning(
|
245
|
+
f"Failed to create message with id: {message_id} in conversation: {conversation_id}"
|
246
|
+
)
|
247
|
+
return False
|
248
|
+
except Exception as e:
|
249
|
+
logger.error(
|
250
|
+
f"Error creating message with id: {message_id} in conversation: {conversation_id}: {e}",
|
251
|
+
exc_info=True,
|
252
|
+
)
|
253
|
+
raise
|
254
|
+
|
255
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
256
|
+
async def update_message_feedback(self, user_id, message_id, feedback):
|
257
|
+
query = "UPDATE messages SET feedback = $1 WHERE id = $2 AND user_id = $3 RETURNING *"
|
258
|
+
try:
|
259
|
+
message = await self.conn.fetchrow(query, feedback, message_id, user_id)
|
260
|
+
if message:
|
261
|
+
logger.info(
|
262
|
+
f"Message feedback updated for message_id: {message_id} and user_id: {user_id}"
|
263
|
+
)
|
264
|
+
return dict(message)
|
265
|
+
else:
|
266
|
+
logger.warning(
|
267
|
+
f"Failed to update message feedback for message_id: {message_id} and user_id: {user_id}"
|
268
|
+
)
|
269
|
+
return False
|
270
|
+
except Exception as e:
|
271
|
+
logger.error(
|
272
|
+
f"Error updating message feedback for message_id: {message_id} and user_id: {user_id}: {e}",
|
273
|
+
exc_info=True,
|
274
|
+
)
|
275
|
+
raise
|
276
|
+
|
277
|
+
@logger.trace_function(log_args=log_args, log_result=log_result)
|
278
|
+
async def get_messages(self, user_id, conversation_id):
|
279
|
+
query = 'SELECT * FROM messages WHERE conversation_id = $1 AND user_id = $2 ORDER BY "createdAt" ASC'
|
280
|
+
try:
|
281
|
+
messages = await self.conn.fetch(query, conversation_id, user_id)
|
282
|
+
logger.info(
|
283
|
+
f"Retrieved messages for conversation_id: {conversation_id} and user_id: {user_id}"
|
284
|
+
)
|
285
|
+
return [dict(message) for message in messages]
|
286
|
+
except Exception as e:
|
287
|
+
logger.error(
|
288
|
+
f"Error retrieving messages for conversation_id: {conversation_id} and user_id: {user_id}: {e}",
|
289
|
+
exc_info=True,
|
290
|
+
)
|
291
|
+
raise
|