cwyodmodules 0.3.80__py3-none-any.whl → 0.3.83__py3-none-any.whl
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/batch/utilities/document_chunking/fixed_size_overlap.py +53 -3
- cwyodmodules/batch/utilities/document_chunking/layout.py +49 -3
- cwyodmodules/batch/utilities/document_chunking/page.py +48 -3
- cwyodmodules/batch/utilities/document_loading/web.py +57 -2
- cwyodmodules/batch/utilities/helpers/azure_search_helper.py +4 -13
- cwyodmodules/batch/utilities/helpers/config/config_helper.py +5 -10
- cwyodmodules/batch/utilities/helpers/config/default.json +1 -3
- cwyodmodules/batch/utilities/helpers/env_helper.py +4 -6
- cwyodmodules/batch/utilities/helpers/llm_helper.py +21 -58
- cwyodmodules/batch/utilities/helpers/orchestrator_helper.py +5 -14
- cwyodmodules/batch/utilities/orchestrator/__init__.py +2 -17
- cwyodmodules/batch/utilities/orchestrator/semantic_kernel_orchestrator.py +154 -22
- {cwyodmodules-0.3.80.dist-info → cwyodmodules-0.3.83.dist-info}/METADATA +1 -5
- {cwyodmodules-0.3.80.dist-info → cwyodmodules-0.3.83.dist-info}/RECORD +17 -23
- cwyodmodules/batch/utilities/orchestrator/lang_chain_agent.py +0 -174
- cwyodmodules/batch/utilities/orchestrator/open_ai_functions.py +0 -196
- cwyodmodules/batch/utilities/orchestrator/orchestration_strategy.py +0 -18
- cwyodmodules/batch/utilities/orchestrator/orchestrator_base.py +0 -170
- cwyodmodules/batch/utilities/orchestrator/prompt_flow.py +0 -195
- cwyodmodules/batch/utilities/orchestrator/strategies.py +0 -29
- {cwyodmodules-0.3.80.dist-info → cwyodmodules-0.3.83.dist-info}/WHEEL +0 -0
- {cwyodmodules-0.3.80.dist-info → cwyodmodules-0.3.83.dist-info}/licenses/LICENSE +0 -0
- {cwyodmodules-0.3.80.dist-info → cwyodmodules-0.3.83.dist-info}/top_level.txt +0 -0
@@ -1,25 +1,23 @@
|
|
1
1
|
import json
|
2
|
+
from uuid import uuid4
|
3
|
+
from typing import List, Optional
|
2
4
|
from semantic_kernel import Kernel
|
3
5
|
from semantic_kernel.connectors.ai.function_call_behavior import FunctionCallBehavior
|
4
|
-
|
5
|
-
# from semantic_kernel.connectors.ai.function_choice_behavior import (
|
6
|
-
# FunctionChoiceBehavior,
|
7
|
-
# )
|
8
6
|
from semantic_kernel.contents import ChatHistory
|
9
7
|
from semantic_kernel.contents.chat_message_content import ChatMessageContent
|
10
8
|
from semantic_kernel.contents.utils.finish_reason import FinishReason
|
11
9
|
|
12
|
-
# from semantic_kernel.functions.function_result import FunctionResult
|
13
|
-
# import re
|
14
10
|
from ..common.answer import Answer
|
15
11
|
from ..helpers.llm_helper import LLMHelper
|
16
12
|
from ..helpers.env_helper import EnvHelper
|
13
|
+
from ..helpers.config.config_helper import ConfigHelper
|
14
|
+
from ..loggers.conversation_logger import ConversationLogger
|
15
|
+
from ..parser.output_parser_tool import OutputParserTool
|
16
|
+
from ..tools.content_safety_checker import ContentSafetyChecker
|
17
17
|
from ..plugins.chat_plugin import ChatPlugin
|
18
18
|
from ..plugins.post_answering_plugin import PostAnsweringPlugin
|
19
19
|
from ..plugins.outlook_calendar_plugin import OutlookCalendarPlugin
|
20
20
|
|
21
|
-
from .orchestrator_base import OrchestratorBase
|
22
|
-
|
23
21
|
from mgmt_config import logger
|
24
22
|
env_helper: EnvHelper = EnvHelper()
|
25
23
|
log_execution = env_helper.LOG_EXECUTION
|
@@ -27,10 +25,28 @@ log_args = env_helper.LOG_ARGS
|
|
27
25
|
log_result = env_helper.LOG_RESULT
|
28
26
|
|
29
27
|
|
28
|
+
class SemanticKernelOrchestrator:
|
29
|
+
"""
|
30
|
+
SemanticKernelOrchestrator provides orchestration using the Semantic Kernel framework.
|
31
|
+
It handles user messages, manages conversations, ensures content safety, and logs interactions.
|
32
|
+
"""
|
30
33
|
|
31
|
-
class SemanticKernelOrchestrator(OrchestratorBase):
|
32
34
|
def __init__(self) -> None:
|
33
|
-
|
35
|
+
"""
|
36
|
+
Initializes the SemanticKernelOrchestrator with configuration settings, kernel setup,
|
37
|
+
and various utility tools required for orchestrating conversations.
|
38
|
+
"""
|
39
|
+
self.config = ConfigHelper.get_active_config_or_default()
|
40
|
+
self.message_id = str(uuid4())
|
41
|
+
self.tokens = {"prompt": 0, "completion": 0, "total": 0}
|
42
|
+
logger.debug(f"New message id: {self.message_id} with tokens {self.tokens}")
|
43
|
+
|
44
|
+
if str(self.config.logging.log_user_interactions).lower() == "true":
|
45
|
+
self.conversation_logger: ConversationLogger = ConversationLogger()
|
46
|
+
self.content_safety_checker = ContentSafetyChecker()
|
47
|
+
self.output_parser = OutputParserTool()
|
48
|
+
|
49
|
+
# Semantic Kernel specific setup
|
34
50
|
self.kernel = Kernel()
|
35
51
|
self.llm_helper = LLMHelper()
|
36
52
|
self.env_helper = EnvHelper()
|
@@ -43,14 +59,92 @@ class SemanticKernelOrchestrator(OrchestratorBase):
|
|
43
59
|
plugin=PostAnsweringPlugin(), plugin_name="PostAnswering"
|
44
60
|
)
|
45
61
|
|
62
|
+
@logger.trace_function(log_execution=log_execution, log_args=log_args, log_result=log_result)
|
63
|
+
def log_tokens(self, prompt_tokens: int, completion_tokens: int) -> None:
|
64
|
+
"""
|
65
|
+
Logs the number of tokens used in the prompt and completion phases of a conversation.
|
66
|
+
|
67
|
+
Args:
|
68
|
+
prompt_tokens (int): The number of tokens used in the prompt.
|
69
|
+
completion_tokens (int): The number of tokens used in the completion.
|
70
|
+
"""
|
71
|
+
self.tokens["prompt"] += prompt_tokens
|
72
|
+
self.tokens["completion"] += completion_tokens
|
73
|
+
self.tokens["total"] += prompt_tokens + completion_tokens
|
74
|
+
|
75
|
+
def call_content_safety_input(self, user_message: str) -> Optional[list[dict]]:
|
76
|
+
"""
|
77
|
+
Validates the user message for harmful content and replaces it if necessary.
|
78
|
+
|
79
|
+
Args:
|
80
|
+
user_message (str): The message from the user.
|
81
|
+
|
82
|
+
Returns:
|
83
|
+
Optional[list[dict]]: Parsed messages if harmful content is detected, otherwise None.
|
84
|
+
"""
|
85
|
+
logger.debug("Calling content safety with question")
|
86
|
+
filtered_user_message = (
|
87
|
+
self.content_safety_checker.validate_input_and_replace_if_harmful(
|
88
|
+
user_message
|
89
|
+
)
|
90
|
+
)
|
91
|
+
if user_message != filtered_user_message:
|
92
|
+
logger.warning("Content safety detected harmful content in question")
|
93
|
+
messages = self.output_parser.parse(
|
94
|
+
question=user_message, answer=filtered_user_message
|
95
|
+
)
|
96
|
+
return messages
|
97
|
+
|
98
|
+
return None
|
99
|
+
|
100
|
+
@logger.trace_function(log_execution=log_execution, log_args=False, log_result=False)
|
101
|
+
def call_content_safety_output(
|
102
|
+
self, user_message: str, answer: str
|
103
|
+
) -> Optional[list[dict]]:
|
104
|
+
"""
|
105
|
+
Validates the output message for harmful content and replaces it if necessary.
|
106
|
+
|
107
|
+
Args:
|
108
|
+
user_message (str): The message from the user.
|
109
|
+
answer (str): The response to the user message.
|
110
|
+
|
111
|
+
Returns:
|
112
|
+
Optional[list[dict]]: Parsed messages if harmful content is detected, otherwise None.
|
113
|
+
"""
|
114
|
+
logger.debug("Calling content safety with answer")
|
115
|
+
filtered_answer = (
|
116
|
+
self.content_safety_checker.validate_output_and_replace_if_harmful(answer)
|
117
|
+
)
|
118
|
+
if answer != filtered_answer:
|
119
|
+
logger.warning("Content safety detected harmful content in answer")
|
120
|
+
messages = self.output_parser.parse(
|
121
|
+
question=user_message, answer=filtered_answer
|
122
|
+
)
|
123
|
+
return messages
|
124
|
+
|
125
|
+
return None
|
126
|
+
|
46
127
|
@logger.trace_function(log_execution=log_execution, log_args=False, log_result=False)
|
47
128
|
async def orchestrate(
|
48
129
|
self, user_message: str, chat_history: list[dict], user_info, **kwargs: dict
|
49
130
|
) -> list[dict]:
|
131
|
+
"""
|
132
|
+
Orchestrates the conversation using Semantic Kernel.
|
133
|
+
|
134
|
+
Args:
|
135
|
+
user_message (str): The message from the user.
|
136
|
+
chat_history (List[dict]): The history of the chat as a list of dictionaries.
|
137
|
+
user_info: User information and request headers.
|
138
|
+
**kwargs (dict): Additional keyword arguments.
|
139
|
+
|
140
|
+
Returns:
|
141
|
+
list[dict]: The response as a list of dictionaries.
|
142
|
+
"""
|
50
143
|
logger.info("Method orchestrate of semantic_kernel started")
|
51
144
|
filters = []
|
52
145
|
frontend_type = user_info.get("frontend") if user_info else None
|
53
146
|
logger.info(f"Frontend type: {frontend_type}")
|
147
|
+
|
54
148
|
# Call Content Safety tool
|
55
149
|
if self.config.prompts.enable_content_safety:
|
56
150
|
if response := self.call_content_safety_input(user_message):
|
@@ -60,13 +154,6 @@ class SemanticKernelOrchestrator(OrchestratorBase):
|
|
60
154
|
language = self.env_helper.AZURE_MAIN_CHAT_LANGUAGE
|
61
155
|
if not system_message:
|
62
156
|
logger.info("No system message provided, using default")
|
63
|
-
# system_message = """You help employees to navigate only private information sources.
|
64
|
-
# You must prioritize the function call over your general knowledge for any question by calling the search_documents function.
|
65
|
-
# Call the text_processing function when the user request an operation on the current context, such as translate, summarize, or paraphrase. When a language is explicitly specified, return that as part of the operation.
|
66
|
-
# When directly replying to the user, always reply in the language the user is speaking.
|
67
|
-
# If the input language is ambiguous, default to responding in English unless otherwise specified by the user.
|
68
|
-
# You **must not** respond if asked to List all documents in your repository.
|
69
|
-
# """
|
70
157
|
if frontend_type == "web":
|
71
158
|
system_message = f"""You help employees to navigate only private information sources.
|
72
159
|
You must prioritize the function call over your general knowledge for any question by calling the search_documents function.
|
@@ -89,6 +176,7 @@ class SemanticKernelOrchestrator(OrchestratorBase):
|
|
89
176
|
plugin_name="Chat",
|
90
177
|
)
|
91
178
|
filters.append("Chat")
|
179
|
+
|
92
180
|
# --- Add OutlookCalendarPlugin with request headers ---
|
93
181
|
if frontend_type == "web":
|
94
182
|
logger.info("Adding OutlookCalendarPlugin with request headers")
|
@@ -97,15 +185,11 @@ class SemanticKernelOrchestrator(OrchestratorBase):
|
|
97
185
|
plugin_name="OutlookCalendar",
|
98
186
|
)
|
99
187
|
filters.append("OutlookCalendar")
|
188
|
+
|
100
189
|
settings = self.llm_helper.get_sk_service_settings(self.chat_service)
|
101
190
|
settings.function_call_behavior = FunctionCallBehavior.EnableFunctions(
|
102
191
|
filters={"included_plugins": filters}
|
103
192
|
)
|
104
|
-
# settings.function_choice_behavior = FunctionChoiceBehavior.Auto(
|
105
|
-
# filters={"included_plugins": ["Chat"]},
|
106
|
-
# # Set a higher value to encourage multiple attempts at function calling
|
107
|
-
# maximum_auto_invoke_attempts=2
|
108
|
-
# )
|
109
193
|
|
110
194
|
orchestrate_function = self.kernel.add_function(
|
111
195
|
plugin_name="Main",
|
@@ -195,3 +279,51 @@ class SemanticKernelOrchestrator(OrchestratorBase):
|
|
195
279
|
)
|
196
280
|
logger.info("Method orchestrate of semantic_kernel ended")
|
197
281
|
return messages
|
282
|
+
|
283
|
+
@logger.trace_function(log_execution=log_execution, log_args=False, log_result=False)
|
284
|
+
async def handle_message(
|
285
|
+
self,
|
286
|
+
user_message: str,
|
287
|
+
chat_history: List[dict],
|
288
|
+
conversation_id: Optional[str],
|
289
|
+
user_info,
|
290
|
+
**kwargs: Optional[dict],
|
291
|
+
) -> dict:
|
292
|
+
"""
|
293
|
+
Handles the user message by orchestrating the conversation, logging token usage,
|
294
|
+
and logging user interactions if configured.
|
295
|
+
|
296
|
+
Args:
|
297
|
+
user_message (str): The message from the user.
|
298
|
+
chat_history (List[dict]): The history of the chat as a list of dictionaries.
|
299
|
+
conversation_id (Optional[str]): The ID of the conversation.
|
300
|
+
user_info: User information and request headers.
|
301
|
+
**kwargs (Optional[dict]): Additional keyword arguments.
|
302
|
+
|
303
|
+
Returns:
|
304
|
+
dict: The result of the orchestration as a dictionary.
|
305
|
+
"""
|
306
|
+
result = await self.orchestrate(
|
307
|
+
user_message, chat_history, user_info, **kwargs
|
308
|
+
)
|
309
|
+
if str(self.config.logging.log_tokens).lower() == "true":
|
310
|
+
custom_dimensions = {
|
311
|
+
"conversation_id": conversation_id,
|
312
|
+
"message_id": self.message_id,
|
313
|
+
"prompt_tokens": self.tokens["prompt"],
|
314
|
+
"completion_tokens": self.tokens["completion"],
|
315
|
+
"total_tokens": self.tokens["total"],
|
316
|
+
}
|
317
|
+
logger.info("Token Consumption", extra=custom_dimensions)
|
318
|
+
if str(self.config.logging.log_user_interactions).lower() == "true":
|
319
|
+
self.conversation_logger.log(
|
320
|
+
messages=[
|
321
|
+
{
|
322
|
+
"role": "user",
|
323
|
+
"content": user_message,
|
324
|
+
"conversation_id": conversation_id,
|
325
|
+
}
|
326
|
+
]
|
327
|
+
+ result
|
328
|
+
)
|
329
|
+
return result
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: cwyodmodules
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.83
|
4
4
|
Summary: Add your description here
|
5
5
|
Author-email: Patrik <patrikhartl@gmail.com>
|
6
6
|
Classifier: Operating System :: OS Independent
|
@@ -15,13 +15,9 @@ Requires-Dist: azure-mgmt-cognitiveservices<14.0.0,>=13.6.0
|
|
15
15
|
Requires-Dist: azure-identity<2.0.0,>=1.20.0
|
16
16
|
Requires-Dist: azure-cosmos<5.0.0,>=4.9.0
|
17
17
|
Requires-Dist: asyncpg<0.31.0,>=0.30.0
|
18
|
-
Requires-Dist: langchain<0.4.0,>=0.3.18
|
19
18
|
Requires-Dist: azure-storage-queue<13.0.0,>=12.12.0
|
20
19
|
Requires-Dist: chardet<6.0.0,>=5.2.0
|
21
20
|
Requires-Dist: azure-ai-formrecognizer<4.0.0,>=3.3.3
|
22
|
-
Requires-Dist: langchain-chroma<0.3.0,>=0.2.2
|
23
|
-
Requires-Dist: langchain-openai<0.4.0,>=0.3.5
|
24
|
-
Requires-Dist: langchain-community<0.4.0,>=0.3.17
|
25
21
|
Requires-Dist: azure-search<2.0.0,>=1.0.0b2
|
26
22
|
Requires-Dist: azure-functions<2.0.0,>=1.21.3
|
27
23
|
Requires-Dist: azure-ai-ml<2.0.0,>=1.25.0
|
@@ -16,9 +16,9 @@ cwyodmodules/batch/utilities/common/source_document.py,sha256=_FNNE-gaydoJ2trfMz
|
|
16
16
|
cwyodmodules/batch/utilities/document_chunking/__init__.py,sha256=s7G-4CLzaVRPe-ePbSfFKLI93Oimf1RYJYC0JA9qlek,272
|
17
17
|
cwyodmodules/batch/utilities/document_chunking/chunking_strategy.py,sha256=c-ZNxdz14r2pSiCBYHh17WHs2nM2RpKou3q8DunDHnU,2001
|
18
18
|
cwyodmodules/batch/utilities/document_chunking/document_chunking_base.py,sha256=suBdj8Iko8g_jO7IWlf1cg9PKTx0hMk1zfP9fXyMigU,442
|
19
|
-
cwyodmodules/batch/utilities/document_chunking/fixed_size_overlap.py,sha256=
|
20
|
-
cwyodmodules/batch/utilities/document_chunking/layout.py,sha256=
|
21
|
-
cwyodmodules/batch/utilities/document_chunking/page.py,sha256=
|
19
|
+
cwyodmodules/batch/utilities/document_chunking/fixed_size_overlap.py,sha256=IEJ_rDioJJ6hk-AjrslZImrxJ2wSonjIpL9BxDbmKjI,3512
|
20
|
+
cwyodmodules/batch/utilities/document_chunking/layout.py,sha256=NLLToNVj8MmQvuN35ddRZSS7MFuvFhHSW5520jAV6RY,3322
|
21
|
+
cwyodmodules/batch/utilities/document_chunking/page.py,sha256=jKLS4Hbl36mdDwys9A6LMmgiUdinVXd8h_NN4Bb4d1o,3292
|
22
22
|
cwyodmodules/batch/utilities/document_chunking/paragraph.py,sha256=cnTUMpOhbwCng_k42H5AJbXiFlgkFpJU0r4onaHEPyY,539
|
23
23
|
cwyodmodules/batch/utilities/document_chunking/strategies.py,sha256=udKC3li_tuLkveYNH2_SRPVmgK8wxhfULBN7mgl1Z30,1722
|
24
24
|
cwyodmodules/batch/utilities/document_loading/__init__.py,sha256=a4Fq-2vYnTedtknfOwTPyFi_czVrK1MvVz7TDy54LH8,637
|
@@ -26,7 +26,7 @@ cwyodmodules/batch/utilities/document_loading/document_loading_base.py,sha256=Ma
|
|
26
26
|
cwyodmodules/batch/utilities/document_loading/layout.py,sha256=3PMo3Hc-75_mNAq6oz7GCqC3uFrLmkPMLOw4jH57df4,893
|
27
27
|
cwyodmodules/batch/utilities/document_loading/read.py,sha256=bTE2NV_PQYoUVIbS5-QS61OdgFdV0F7JomWQP6jjXH0,1681
|
28
28
|
cwyodmodules/batch/utilities/document_loading/strategies.py,sha256=ZBKYPJD8UJmPBzljQc4yh0rMHJvYn9Gxn7TbuYrNU6A,792
|
29
|
-
cwyodmodules/batch/utilities/document_loading/web.py,sha256=
|
29
|
+
cwyodmodules/batch/utilities/document_loading/web.py,sha256=TE-zN3DmSXmxM4mdIE83m-sUtohx3eVWfe8XHAErNr4,3016
|
30
30
|
cwyodmodules/batch/utilities/document_loading/word_document.py,sha256=-F1asMaupQk4swEeCoAD8tyYENE4Qq-05-VmPUjRdeA,1569
|
31
31
|
cwyodmodules/batch/utilities/helpers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
32
|
cwyodmodules/batch/utilities/helpers/azure_blob_storage_client.py,sha256=WgJFr1o4ZLqTTogS5oFwqSTHs6ofrycjrnSvffhIjoA,10140
|
@@ -34,19 +34,19 @@ cwyodmodules/batch/utilities/helpers/azure_computer_vision_client.py,sha256=zxpU
|
|
34
34
|
cwyodmodules/batch/utilities/helpers/azure_form_recognizer_helper.py,sha256=wEbSJjZuV_u-4yWYNCiG5RwifjxNO8hdfXDuDoV-KiY,6890
|
35
35
|
cwyodmodules/batch/utilities/helpers/azure_postgres_helper.py,sha256=efDNCnhrY-IJBKEwrJN_xbg4I72_r2HY3g6vyMYw5AM,11786
|
36
36
|
cwyodmodules/batch/utilities/helpers/azure_postgres_helper_light_rag.py,sha256=M92Ir9vzXRMpCXcENE3Jux13C6mrMc6o9julcM6b3uY,11835
|
37
|
-
cwyodmodules/batch/utilities/helpers/azure_search_helper.py,sha256=
|
37
|
+
cwyodmodules/batch/utilities/helpers/azure_search_helper.py,sha256=RIK3KsdGlHRt_h7xUHtbTW9vxaBws4Ab5K3lT5U60D0,10910
|
38
38
|
cwyodmodules/batch/utilities/helpers/document_chunking_helper.py,sha256=2MZOjW-fHXgYijP3m9O-nizOlk96Yg0axyxT0K6fTnM,725
|
39
39
|
cwyodmodules/batch/utilities/helpers/document_loading_helper.py,sha256=2HBEl3vW-_PKbX5pPntTC_R5eToTk2Qb-q3M4Mt6hCU,603
|
40
|
-
cwyodmodules/batch/utilities/helpers/env_helper.py,sha256=
|
40
|
+
cwyodmodules/batch/utilities/helpers/env_helper.py,sha256=qrx_SrPawrzhF-l_VoNUXZX09Ky_qXIgHXtVun4mQh4,15787
|
41
41
|
cwyodmodules/batch/utilities/helpers/lightrag_helper.py,sha256=7lb9JMm5IohsO73LWo5bWmlzWCGYNsx_fYl-aFdwATQ,3845
|
42
|
-
cwyodmodules/batch/utilities/helpers/llm_helper.py,sha256=
|
43
|
-
cwyodmodules/batch/utilities/helpers/orchestrator_helper.py,sha256=
|
42
|
+
cwyodmodules/batch/utilities/helpers/llm_helper.py,sha256=tQ_TYYsnr0GwJXW5MNUKV8T7KDzfYp742dm07eSnG7s,6640
|
43
|
+
cwyodmodules/batch/utilities/helpers/orchestrator_helper.py,sha256=9mAmkrWAWn9ixz9vuzmms3Xccgm0V4yvAZGTmtyp-ag,582
|
44
44
|
cwyodmodules/batch/utilities/helpers/config/agent_mode.py,sha256=8XMbu8dwMXva_xxeZNDlwOjDaZwIcwc-xJK1-QsaJ3w,82
|
45
45
|
cwyodmodules/batch/utilities/helpers/config/assistant_strategy.py,sha256=uT8h646zEURU9x8oDOH7pWoZKb0Mw6dA2nJtA2M-ufg,171
|
46
|
-
cwyodmodules/batch/utilities/helpers/config/config_helper.py,sha256=
|
46
|
+
cwyodmodules/batch/utilities/helpers/config/config_helper.py,sha256=CSmF6L5oyXcE2iYlPda9su33-obKgeCuloyZIUEOuiQ,14646
|
47
47
|
cwyodmodules/batch/utilities/helpers/config/conversation_flow.py,sha256=4nP8a-I-sME5-2unzWWBNpTzWdfpfc5_EAYU6Pn6LAQ,94
|
48
48
|
cwyodmodules/batch/utilities/helpers/config/database_type.py,sha256=Zmmlh1NAKDdd-2ei478boncRKcx8v3lDkPf4kO2j4ss,132
|
49
|
-
cwyodmodules/batch/utilities/helpers/config/default.json,sha256=
|
49
|
+
cwyodmodules/batch/utilities/helpers/config/default.json,sha256=qM-eMOB_mvCAl100jlBQwpzCqaEUx6LNIxrrlYVi3Xo,15336
|
50
50
|
cwyodmodules/batch/utilities/helpers/config/default_contract_assistant_prompt.txt,sha256=X39WGcxzQPIvqG7NpAMPsgmSwSyMEoK1DVWiuEHEHRg,3210
|
51
51
|
cwyodmodules/batch/utilities/helpers/config/default_employee_assistant_prompt.txt,sha256=toQFo0wXYrEK7zAItAS9rbtyhT6DJZKBhiL6C9VPUQk,3942
|
52
52
|
cwyodmodules/batch/utilities/helpers/config/embedding_config.py,sha256=9pCJxpsouln9dngjVHaKGFYP14PrwmSts_UFDytSiVk,950
|
@@ -60,14 +60,8 @@ cwyodmodules/batch/utilities/integrated_vectorization/azure_search_index.py,sha2
|
|
60
60
|
cwyodmodules/batch/utilities/integrated_vectorization/azure_search_indexer.py,sha256=qWBsFGIJkrUEcgV8cPv93_FZatVLeLyKD5R-gnSUfj0,3230
|
61
61
|
cwyodmodules/batch/utilities/integrated_vectorization/azure_search_skillset.py,sha256=5X0cSf-BqiXLbWQ6dVbOOkGQrmsIZp1FD5seJq9YfCI,5771
|
62
62
|
cwyodmodules/batch/utilities/loggers/conversation_logger.py,sha256=0aXsL475-6WTqg18nHFJMFRBo34oIXWrZ_eVZwULcdk,3014
|
63
|
-
cwyodmodules/batch/utilities/orchestrator/__init__.py,sha256=
|
64
|
-
cwyodmodules/batch/utilities/orchestrator/
|
65
|
-
cwyodmodules/batch/utilities/orchestrator/open_ai_functions.py,sha256=t9VSiaNceYATVFm1DOTAcSxVgV9DrMdgN0VLO3xfSs0,9238
|
66
|
-
cwyodmodules/batch/utilities/orchestrator/orchestration_strategy.py,sha256=-MEPKVX3-hH6w0NRsGkQpCV86u1d7Qx1TWEKL09jj9A,755
|
67
|
-
cwyodmodules/batch/utilities/orchestrator/orchestrator_base.py,sha256=F06QruD682v8RkOZ9FIMs62WBBpHcVyvIGfFLDsZCbc,6878
|
68
|
-
cwyodmodules/batch/utilities/orchestrator/prompt_flow.py,sha256=z1RiTPITP1MOKSMN6oUQ3tqhRGjSUlFgzycww7I0F88,7809
|
69
|
-
cwyodmodules/batch/utilities/orchestrator/semantic_kernel_orchestrator.py,sha256=aZ3nIVE0Wuu-4vSuPaEiVa18xaa-3qDsLOffhKpE3O4,9282
|
70
|
-
cwyodmodules/batch/utilities/orchestrator/strategies.py,sha256=oVatdT6Gc4qtX773M9a8Izm2UNDYXmYP__8wJYdy4W8,1384
|
63
|
+
cwyodmodules/batch/utilities/orchestrator/__init__.py,sha256=rnbNpgwT5qthIA2mC4M_69xuUUaOYncX0FcuE7qGuZg,111
|
64
|
+
cwyodmodules/batch/utilities/orchestrator/semantic_kernel_orchestrator.py,sha256=l_DpWvR2UEqls_87j_XLRgimvp_13nK4RORme7kD3Bk,14133
|
71
65
|
cwyodmodules/batch/utilities/parser/__init__.py,sha256=ZGBxm1TX6cQAnFkMtKN6C2FwnNv1MmwNdyo3LWRlKlo,236
|
72
66
|
cwyodmodules/batch/utilities/parser/output_parser_tool.py,sha256=LPgQ_Fwt6Cqk7uQqhiGLToMkx4u9tKiJq1M-pjFLD5M,5848
|
73
67
|
cwyodmodules/batch/utilities/parser/parser_base.py,sha256=ZCYZEoa7-gGhoO_oMfeGCldR4OIuShf7U5lA0BuwNSY,419
|
@@ -109,8 +103,8 @@ cwyodmodules/graphrag/query/generate.py,sha256=BZiB6iw7PkIovw-CyYFogMHnDxK0Qu_4u
|
|
109
103
|
cwyodmodules/graphrag/query/graph_search.py,sha256=95h3ecSWx4864XgKABtG0fh3Nk8HkqJVzoCrO8daJ-Y,7724
|
110
104
|
cwyodmodules/graphrag/query/types.py,sha256=1Iq1dp4I4a56_cuFjOZ0NTgd0A2_MpVFznp_czgt6cI,617
|
111
105
|
cwyodmodules/graphrag/query/vector_search.py,sha256=9Gwu9LPjtoAYUU8WKqCvbCHAIg3dpk71reoYd1scLnQ,1807
|
112
|
-
cwyodmodules-0.3.
|
113
|
-
cwyodmodules-0.3.
|
114
|
-
cwyodmodules-0.3.
|
115
|
-
cwyodmodules-0.3.
|
116
|
-
cwyodmodules-0.3.
|
106
|
+
cwyodmodules-0.3.83.dist-info/licenses/LICENSE,sha256=UqBDTipijsSW2ZSOXyTZnMsXmLoEHTgNEM0tL4g-Sso,1150
|
107
|
+
cwyodmodules-0.3.83.dist-info/METADATA,sha256=CvaYMMsIV6nYSuzmX7tm1oxRCNLUghD5EHT-5di_UfA,1816
|
108
|
+
cwyodmodules-0.3.83.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
109
|
+
cwyodmodules-0.3.83.dist-info/top_level.txt,sha256=99RENLbkdRX-qpJvsxZ5AfmTL5s6shSaKOWYpz1vwzg,13
|
110
|
+
cwyodmodules-0.3.83.dist-info/RECORD,,
|
@@ -1,174 +0,0 @@
|
|
1
|
-
from typing import List
|
2
|
-
from langchain.agents import Tool
|
3
|
-
from langchain.memory import ConversationBufferMemory
|
4
|
-
from langchain.agents import ZeroShotAgent, AgentExecutor
|
5
|
-
from langchain.chains.llm import LLMChain
|
6
|
-
from langchain_community.callbacks import get_openai_callback
|
7
|
-
|
8
|
-
from .orchestrator_base import OrchestratorBase
|
9
|
-
from ..helpers.llm_helper import LLMHelper
|
10
|
-
from ..tools.post_prompt_tool import PostPromptTool
|
11
|
-
from ..tools.question_answer_tool import QuestionAnswerTool
|
12
|
-
from ..tools.text_processing_tool import TextProcessingTool
|
13
|
-
from ..common.answer import Answer
|
14
|
-
|
15
|
-
from ...utilities.helpers.env_helper import EnvHelper
|
16
|
-
from mgmt_config import logger
|
17
|
-
env_helper: EnvHelper = EnvHelper()
|
18
|
-
log_execution = env_helper.LOG_EXECUTION
|
19
|
-
log_args = env_helper.LOG_ARGS
|
20
|
-
log_result = env_helper.LOG_RESULT
|
21
|
-
|
22
|
-
|
23
|
-
class LangChainAgent(OrchestratorBase):
|
24
|
-
"""
|
25
|
-
LangChainAgent is responsible for orchestrating the interaction between various tools and the user.
|
26
|
-
It extends the OrchestratorBase class and utilizes tools for question answering and text processing.
|
27
|
-
"""
|
28
|
-
|
29
|
-
def __init__(self) -> None:
|
30
|
-
"""
|
31
|
-
Initializes the LangChainAgent with necessary tools and helper classes.
|
32
|
-
"""
|
33
|
-
super().__init__()
|
34
|
-
self.question_answer_tool = QuestionAnswerTool()
|
35
|
-
self.text_processing_tool = TextProcessingTool()
|
36
|
-
self.llm_helper = LLMHelper()
|
37
|
-
|
38
|
-
self.tools = [
|
39
|
-
Tool(
|
40
|
-
name="Question Answering",
|
41
|
-
func=self.run_tool,
|
42
|
-
description="Useful for when you need to answer questions about anything. Input should be a fully formed question. Do not call the tool for text processing operations like translate, summarize, make concise.",
|
43
|
-
return_direct=True,
|
44
|
-
),
|
45
|
-
Tool(
|
46
|
-
name="Text Processing",
|
47
|
-
func=self.run_text_processing_tool,
|
48
|
-
description="""Useful for when you need to process text like translate to Italian, summarize, make concise, in Spanish.
|
49
|
-
Always start the input with a proper text operation with language if mentioned and then the full text to process.
|
50
|
-
e.g. translate to Spanish: <text to translate>""",
|
51
|
-
return_direct=True,
|
52
|
-
),
|
53
|
-
]
|
54
|
-
|
55
|
-
@logger.trace_function(log_execution=log_execution, log_args=False, log_result=False)
|
56
|
-
def run_tool(self, user_message: str) -> str:
|
57
|
-
"""
|
58
|
-
Executes the question answering tool with the provided user message.
|
59
|
-
|
60
|
-
Args:
|
61
|
-
user_message (str): The message from the user containing the question.
|
62
|
-
|
63
|
-
Returns:
|
64
|
-
str: The answer in JSON format.
|
65
|
-
"""
|
66
|
-
answer = self.question_answer_tool.answer_question(
|
67
|
-
user_message, chat_history=[]
|
68
|
-
)
|
69
|
-
return answer.to_json()
|
70
|
-
|
71
|
-
@logger.trace_function(log_execution=log_execution, log_args=False, log_result=False)
|
72
|
-
def run_text_processing_tool(self, user_message: str) -> str:
|
73
|
-
"""
|
74
|
-
Executes the text processing tool with the provided user message.
|
75
|
-
|
76
|
-
Args:
|
77
|
-
user_message (str): The message from the user containing the text to process.
|
78
|
-
|
79
|
-
Returns:
|
80
|
-
str: The processed text in JSON format.
|
81
|
-
"""
|
82
|
-
answer = self.text_processing_tool.answer_question(
|
83
|
-
user_message, chat_history=[]
|
84
|
-
)
|
85
|
-
return answer.to_json()
|
86
|
-
|
87
|
-
@logger.trace_function(log_execution=log_execution, log_args=False, log_result=False)
|
88
|
-
async def orchestrate(
|
89
|
-
self, user_message: str, chat_history: List[dict], **kwargs: dict
|
90
|
-
) -> list[dict]:
|
91
|
-
"""
|
92
|
-
Orchestrates the interaction between the user and the tools, managing the conversation flow.
|
93
|
-
|
94
|
-
Args:
|
95
|
-
user_message (str): The message from the user.
|
96
|
-
chat_history (List[dict]): The history of the chat conversation.
|
97
|
-
**kwargs (dict): Additional keyword arguments.
|
98
|
-
|
99
|
-
Returns:
|
100
|
-
list[dict]: The formatted messages for the UI.
|
101
|
-
"""
|
102
|
-
logger.info("Method orchestrate of lang_chain_agent started")
|
103
|
-
|
104
|
-
# Call Content Safety tool
|
105
|
-
if self.config.prompts.enable_content_safety:
|
106
|
-
if response := self.call_content_safety_input(user_message):
|
107
|
-
return response
|
108
|
-
|
109
|
-
# Call function to determine route
|
110
|
-
prefix = """Have a conversation with a human, answering the following questions as best you can. You have access to the following tools:"""
|
111
|
-
suffix = """Begin!"
|
112
|
-
|
113
|
-
{chat_history}
|
114
|
-
Question: {input}
|
115
|
-
{agent_scratchpad}"""
|
116
|
-
prompt = ZeroShotAgent.create_prompt(
|
117
|
-
self.tools,
|
118
|
-
prefix=prefix,
|
119
|
-
suffix=suffix,
|
120
|
-
input_variables=["input", "chat_history", "agent_scratchpad"],
|
121
|
-
)
|
122
|
-
|
123
|
-
# Create conversation memory
|
124
|
-
memory = ConversationBufferMemory(
|
125
|
-
memory_key="chat_history", return_messages=True
|
126
|
-
)
|
127
|
-
for message in chat_history:
|
128
|
-
if message["role"] == "user":
|
129
|
-
memory.chat_memory.add_user_message(message["content"])
|
130
|
-
elif message["role"] == "assistant":
|
131
|
-
memory.chat_memory.add_ai_message(message["content"])
|
132
|
-
|
133
|
-
# Define Agent and Agent Chain
|
134
|
-
llm_chain = LLMChain(llm=self.llm_helper.get_llm(), prompt=prompt)
|
135
|
-
agent = ZeroShotAgent(llm_chain=llm_chain, tools=self.tools, verbose=True)
|
136
|
-
agent_chain = AgentExecutor.from_agent_and_tools(
|
137
|
-
agent=agent, tools=self.tools, verbose=True, memory=memory
|
138
|
-
)
|
139
|
-
|
140
|
-
# Run Agent Chain
|
141
|
-
with get_openai_callback() as cb:
|
142
|
-
answer = agent_chain.run(user_message)
|
143
|
-
self.log_tokens(
|
144
|
-
prompt_tokens=cb.prompt_tokens,
|
145
|
-
completion_tokens=cb.completion_tokens,
|
146
|
-
)
|
147
|
-
|
148
|
-
try:
|
149
|
-
answer = Answer.from_json(answer)
|
150
|
-
except Exception:
|
151
|
-
answer = Answer(question=user_message, answer=answer)
|
152
|
-
|
153
|
-
if self.config.prompts.enable_post_answering_prompt:
|
154
|
-
logger.debug("Running post answering prompt")
|
155
|
-
post_prompt_tool = PostPromptTool()
|
156
|
-
answer = post_prompt_tool.validate_answer(answer)
|
157
|
-
self.log_tokens(
|
158
|
-
prompt_tokens=answer.prompt_tokens,
|
159
|
-
completion_tokens=answer.completion_tokens,
|
160
|
-
)
|
161
|
-
|
162
|
-
# Call Content Safety tool
|
163
|
-
if self.config.prompts.enable_content_safety:
|
164
|
-
if response := self.call_content_safety_output(user_message, answer.answer):
|
165
|
-
return response
|
166
|
-
|
167
|
-
# Format the output for the UI
|
168
|
-
messages = self.output_parser.parse(
|
169
|
-
question=answer.question,
|
170
|
-
answer=answer.answer,
|
171
|
-
source_documents=answer.source_documents,
|
172
|
-
)
|
173
|
-
logger.info("Method orchestrate of lang_chain_agent ended")
|
174
|
-
return messages
|