unique_toolkit 1.8.1__py3-none-any.whl → 1.23.0__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.
Potentially problematic release.
This version of unique_toolkit might be problematic. Click here for more details.
- unique_toolkit/__init__.py +20 -0
- unique_toolkit/_common/api_calling/human_verification_manager.py +121 -28
- unique_toolkit/_common/chunk_relevancy_sorter/config.py +3 -3
- unique_toolkit/_common/chunk_relevancy_sorter/tests/test_service.py +2 -5
- unique_toolkit/_common/default_language_model.py +9 -3
- unique_toolkit/_common/docx_generator/__init__.py +7 -0
- unique_toolkit/_common/docx_generator/config.py +12 -0
- unique_toolkit/_common/docx_generator/schemas.py +80 -0
- unique_toolkit/_common/docx_generator/service.py +252 -0
- unique_toolkit/_common/docx_generator/template/Doc Template.docx +0 -0
- unique_toolkit/_common/endpoint_builder.py +138 -117
- unique_toolkit/_common/endpoint_requestor.py +240 -14
- unique_toolkit/_common/exception.py +20 -0
- unique_toolkit/_common/feature_flags/schema.py +1 -5
- unique_toolkit/_common/referencing.py +53 -0
- unique_toolkit/_common/string_utilities.py +52 -1
- unique_toolkit/_common/tests/test_referencing.py +521 -0
- unique_toolkit/_common/tests/test_string_utilities.py +506 -0
- unique_toolkit/_common/utils/files.py +43 -0
- unique_toolkit/agentic/debug_info_manager/debug_info_manager.py +16 -6
- unique_toolkit/agentic/debug_info_manager/test/test_debug_info_manager.py +278 -0
- unique_toolkit/agentic/evaluation/config.py +3 -2
- unique_toolkit/agentic/evaluation/context_relevancy/service.py +2 -2
- unique_toolkit/agentic/evaluation/evaluation_manager.py +9 -5
- unique_toolkit/agentic/evaluation/hallucination/constants.py +1 -1
- unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py +26 -3
- unique_toolkit/agentic/history_manager/history_manager.py +14 -11
- unique_toolkit/agentic/history_manager/loop_token_reducer.py +3 -4
- unique_toolkit/agentic/history_manager/utils.py +10 -87
- unique_toolkit/agentic/postprocessor/postprocessor_manager.py +107 -16
- unique_toolkit/agentic/reference_manager/reference_manager.py +1 -1
- unique_toolkit/agentic/responses_api/__init__.py +19 -0
- unique_toolkit/agentic/responses_api/postprocessors/code_display.py +63 -0
- unique_toolkit/agentic/responses_api/postprocessors/generated_files.py +145 -0
- unique_toolkit/agentic/responses_api/stream_handler.py +15 -0
- unique_toolkit/agentic/tools/a2a/__init__.py +18 -2
- unique_toolkit/agentic/tools/a2a/evaluation/__init__.py +2 -0
- unique_toolkit/agentic/tools/a2a/evaluation/_utils.py +3 -3
- unique_toolkit/agentic/tools/a2a/evaluation/config.py +1 -1
- unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +143 -91
- unique_toolkit/agentic/tools/a2a/manager.py +7 -1
- unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py +11 -3
- unique_toolkit/agentic/tools/a2a/postprocessing/_display_utils.py +185 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/_ref_utils.py +73 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/config.py +21 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/display.py +180 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/references.py +101 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display_utils.py +1335 -0
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_ref_utils.py +603 -0
- unique_toolkit/agentic/tools/a2a/prompts.py +46 -0
- unique_toolkit/agentic/tools/a2a/response_watcher/__init__.py +6 -0
- unique_toolkit/agentic/tools/a2a/response_watcher/service.py +91 -0
- unique_toolkit/agentic/tools/a2a/tool/config.py +15 -5
- unique_toolkit/agentic/tools/a2a/tool/service.py +69 -36
- unique_toolkit/agentic/tools/config.py +16 -2
- unique_toolkit/agentic/tools/factory.py +4 -0
- unique_toolkit/agentic/tools/mcp/tool_wrapper.py +7 -35
- unique_toolkit/agentic/tools/openai_builtin/__init__.py +11 -0
- unique_toolkit/agentic/tools/openai_builtin/base.py +30 -0
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/__init__.py +8 -0
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/config.py +57 -0
- unique_toolkit/agentic/tools/openai_builtin/code_interpreter/service.py +230 -0
- unique_toolkit/agentic/tools/openai_builtin/manager.py +62 -0
- unique_toolkit/agentic/tools/test/test_mcp_manager.py +95 -7
- unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py +240 -0
- unique_toolkit/agentic/tools/tool.py +0 -11
- unique_toolkit/agentic/tools/tool_manager.py +337 -122
- unique_toolkit/agentic/tools/tool_progress_reporter.py +81 -15
- unique_toolkit/agentic/tools/utils/__init__.py +18 -0
- unique_toolkit/agentic/tools/utils/execution/execution.py +8 -4
- unique_toolkit/agentic/tools/utils/source_handling/schema.py +1 -1
- unique_toolkit/chat/__init__.py +8 -1
- unique_toolkit/chat/deprecated/service.py +232 -0
- unique_toolkit/chat/functions.py +54 -40
- unique_toolkit/chat/rendering.py +34 -0
- unique_toolkit/chat/responses_api.py +461 -0
- unique_toolkit/chat/schemas.py +1 -1
- unique_toolkit/chat/service.py +96 -1569
- unique_toolkit/content/functions.py +116 -1
- unique_toolkit/content/schemas.py +59 -0
- unique_toolkit/content/service.py +5 -37
- unique_toolkit/content/smart_rules.py +301 -0
- unique_toolkit/framework_utilities/langchain/client.py +27 -3
- unique_toolkit/framework_utilities/openai/client.py +12 -1
- unique_toolkit/framework_utilities/openai/message_builder.py +85 -1
- unique_toolkit/language_model/default_language_model.py +3 -0
- unique_toolkit/language_model/functions.py +25 -9
- unique_toolkit/language_model/infos.py +72 -4
- unique_toolkit/language_model/schemas.py +246 -40
- unique_toolkit/protocols/support.py +91 -9
- unique_toolkit/services/__init__.py +7 -0
- unique_toolkit/services/chat_service.py +1630 -0
- unique_toolkit/services/knowledge_base.py +861 -0
- unique_toolkit/smart_rules/compile.py +56 -301
- unique_toolkit/test_utilities/events.py +197 -0
- {unique_toolkit-1.8.1.dist-info → unique_toolkit-1.23.0.dist-info}/METADATA +173 -3
- {unique_toolkit-1.8.1.dist-info → unique_toolkit-1.23.0.dist-info}/RECORD +99 -67
- unique_toolkit/agentic/tools/a2a/postprocessing/_display.py +0 -122
- unique_toolkit/agentic/tools/a2a/postprocessing/_utils.py +0 -19
- unique_toolkit/agentic/tools/a2a/postprocessing/postprocessor.py +0 -230
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_consolidate_references.py +0 -665
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py +0 -391
- unique_toolkit/agentic/tools/a2a/postprocessing/test/test_postprocessor_reference_functions.py +0 -256
- {unique_toolkit-1.8.1.dist-info → unique_toolkit-1.23.0.dist-info}/LICENSE +0 -0
- {unique_toolkit-1.8.1.dist-info → unique_toolkit-1.23.0.dist-info}/WHEEL +0 -0
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
import logging
|
|
2
|
-
from typing import TypedDict, override
|
|
3
|
-
|
|
4
|
-
import unique_sdk
|
|
5
|
-
|
|
6
|
-
from unique_toolkit.agentic.postprocessor.postprocessor_manager import Postprocessor
|
|
7
|
-
from unique_toolkit.agentic.tools.a2a.postprocessing._display import (
|
|
8
|
-
_build_sub_agent_answer_display,
|
|
9
|
-
_remove_sub_agent_answer_from_text,
|
|
10
|
-
)
|
|
11
|
-
from unique_toolkit.agentic.tools.a2a.postprocessing._utils import (
|
|
12
|
-
_replace_references_in_text,
|
|
13
|
-
)
|
|
14
|
-
from unique_toolkit.agentic.tools.a2a.postprocessing.config import (
|
|
15
|
-
SubAgentDisplayConfig,
|
|
16
|
-
SubAgentResponseDisplayMode,
|
|
17
|
-
)
|
|
18
|
-
from unique_toolkit.agentic.tools.a2a.tool import SubAgentTool
|
|
19
|
-
from unique_toolkit.content.schemas import ContentReference
|
|
20
|
-
from unique_toolkit.language_model.schemas import LanguageModelStreamResponse
|
|
21
|
-
|
|
22
|
-
logger = logging.getLogger(__name__)
|
|
23
|
-
|
|
24
|
-
SpaceMessage = unique_sdk.Space.Message
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class _SubAgentMessageInfo(TypedDict):
|
|
28
|
-
text: str
|
|
29
|
-
references: list[unique_sdk.Space.Reference]
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class _SubAgentToolInfo(TypedDict):
|
|
33
|
-
display_name: str
|
|
34
|
-
display_config: SubAgentDisplayConfig
|
|
35
|
-
responses: dict[int, _SubAgentMessageInfo]
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
class SubAgentResponsesPostprocessor(Postprocessor):
|
|
39
|
-
def __init__(
|
|
40
|
-
self,
|
|
41
|
-
user_id: str,
|
|
42
|
-
company_id: str,
|
|
43
|
-
main_agent_chat_id: str,
|
|
44
|
-
) -> None:
|
|
45
|
-
super().__init__(name=self.__class__.__name__)
|
|
46
|
-
|
|
47
|
-
self._user_id = user_id
|
|
48
|
-
self._company_id = company_id
|
|
49
|
-
self._main_agent_chat_id = main_agent_chat_id
|
|
50
|
-
|
|
51
|
-
self._assistant_id_to_tool_info: dict[str, _SubAgentToolInfo] = {}
|
|
52
|
-
self._main_agent_message: SpaceMessage | None = None
|
|
53
|
-
|
|
54
|
-
@override
|
|
55
|
-
async def run(self, loop_response: LanguageModelStreamResponse) -> None:
|
|
56
|
-
self._main_agent_message = await unique_sdk.Space.get_latest_message_async(
|
|
57
|
-
user_id=self._user_id,
|
|
58
|
-
company_id=self._company_id,
|
|
59
|
-
chat_id=self._main_agent_chat_id,
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
@override
|
|
63
|
-
def apply_postprocessing_to_response(
|
|
64
|
-
self, loop_response: LanguageModelStreamResponse
|
|
65
|
-
) -> bool:
|
|
66
|
-
logger.info("Prepending sub agent responses to the main agent response")
|
|
67
|
-
|
|
68
|
-
if len(self._assistant_id_to_tool_info) == 0 or all(
|
|
69
|
-
len(tool_info["responses"]) == 0
|
|
70
|
-
for tool_info in self._assistant_id_to_tool_info.values()
|
|
71
|
-
):
|
|
72
|
-
logger.info("No sub agent responses to prepend")
|
|
73
|
-
return False
|
|
74
|
-
|
|
75
|
-
if self._main_agent_message is None:
|
|
76
|
-
raise ValueError(
|
|
77
|
-
"Main agent message is not set, the `run` method must be called first"
|
|
78
|
-
)
|
|
79
|
-
|
|
80
|
-
existing_refs = {
|
|
81
|
-
ref.source_id: ref.sequence_number
|
|
82
|
-
for ref in loop_response.message.references
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
_consolidate_references_in_place(
|
|
86
|
-
list(self._assistant_id_to_tool_info.values()), existing_refs
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
answers = []
|
|
90
|
-
for assistant_id in self._assistant_id_to_tool_info.keys():
|
|
91
|
-
messages = self._assistant_id_to_tool_info[assistant_id]["responses"]
|
|
92
|
-
|
|
93
|
-
for sequence_number in sorted(messages):
|
|
94
|
-
message = messages[sequence_number]
|
|
95
|
-
tool_info = self._assistant_id_to_tool_info[assistant_id]
|
|
96
|
-
|
|
97
|
-
display_mode = tool_info["display_config"].mode
|
|
98
|
-
display_name = tool_info["display_name"]
|
|
99
|
-
if len(messages) > 1:
|
|
100
|
-
display_name += f" {sequence_number}"
|
|
101
|
-
|
|
102
|
-
answers.append(
|
|
103
|
-
_build_sub_agent_answer_display(
|
|
104
|
-
display_name=display_name,
|
|
105
|
-
assistant_id=assistant_id,
|
|
106
|
-
display_mode=display_mode,
|
|
107
|
-
answer=message["text"],
|
|
108
|
-
)
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
loop_response.message.references.extend(
|
|
112
|
-
ContentReference(
|
|
113
|
-
message_id=self._main_agent_message["id"],
|
|
114
|
-
source_id=ref["sourceId"],
|
|
115
|
-
url=ref["url"] or "",
|
|
116
|
-
source=ref["source"],
|
|
117
|
-
name=ref["name"],
|
|
118
|
-
sequence_number=ref["sequenceNumber"],
|
|
119
|
-
)
|
|
120
|
-
for ref in message["references"]
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
loop_response.message.text = "\n".join(answers) + loop_response.message.text
|
|
124
|
-
|
|
125
|
-
return True
|
|
126
|
-
|
|
127
|
-
@override
|
|
128
|
-
async def remove_from_text(self, text) -> str:
|
|
129
|
-
for assistant_id, tool_info in self._assistant_id_to_tool_info.items():
|
|
130
|
-
display_config = tool_info["display_config"]
|
|
131
|
-
if display_config.remove_from_history:
|
|
132
|
-
text = _remove_sub_agent_answer_from_text(
|
|
133
|
-
display_mode=display_config.mode,
|
|
134
|
-
text=text,
|
|
135
|
-
assistant_id=assistant_id,
|
|
136
|
-
)
|
|
137
|
-
return text
|
|
138
|
-
|
|
139
|
-
def register_sub_agent_tool(
|
|
140
|
-
self, tool: SubAgentTool, display_config: SubAgentDisplayConfig
|
|
141
|
-
) -> None:
|
|
142
|
-
if display_config.mode == SubAgentResponseDisplayMode.HIDDEN:
|
|
143
|
-
logger.info(
|
|
144
|
-
"Sub agent tool %s has display mode `hidden`, responses will be ignored.",
|
|
145
|
-
tool.config.assistant_id,
|
|
146
|
-
)
|
|
147
|
-
return
|
|
148
|
-
|
|
149
|
-
if tool.config.assistant_id not in self._assistant_id_to_tool_info:
|
|
150
|
-
tool.subscribe(self)
|
|
151
|
-
self._assistant_id_to_tool_info[tool.config.assistant_id] = (
|
|
152
|
-
_SubAgentToolInfo(
|
|
153
|
-
display_config=display_config,
|
|
154
|
-
display_name=tool.display_name(),
|
|
155
|
-
responses={},
|
|
156
|
-
)
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
def notify_sub_agent_response(
|
|
160
|
-
self, response: SpaceMessage, sub_agent_assistant_id: str, sequence_number: int
|
|
161
|
-
) -> None:
|
|
162
|
-
if sub_agent_assistant_id not in self._assistant_id_to_tool_info:
|
|
163
|
-
logger.warning(
|
|
164
|
-
"Unknown assistant id %s received, message will be ignored.",
|
|
165
|
-
sub_agent_assistant_id,
|
|
166
|
-
)
|
|
167
|
-
return
|
|
168
|
-
|
|
169
|
-
if response["text"] is None:
|
|
170
|
-
logger.warning(
|
|
171
|
-
"Sub agent response %s has no text, message will be ignored.",
|
|
172
|
-
sequence_number,
|
|
173
|
-
)
|
|
174
|
-
return
|
|
175
|
-
|
|
176
|
-
self._assistant_id_to_tool_info[sub_agent_assistant_id]["responses"][
|
|
177
|
-
sequence_number
|
|
178
|
-
] = {
|
|
179
|
-
"text": response["text"],
|
|
180
|
-
"references": [
|
|
181
|
-
{
|
|
182
|
-
"name": ref["name"],
|
|
183
|
-
"url": ref["url"],
|
|
184
|
-
"sequenceNumber": ref["sequenceNumber"],
|
|
185
|
-
"originalIndex": [],
|
|
186
|
-
"sourceId": ref["sourceId"],
|
|
187
|
-
"source": ref["source"],
|
|
188
|
-
}
|
|
189
|
-
for ref in response["references"] or []
|
|
190
|
-
],
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
def _consolidate_references_in_place(
|
|
195
|
-
messages: list[_SubAgentToolInfo], existing_refs: dict[str, int]
|
|
196
|
-
) -> None:
|
|
197
|
-
start_index = max(existing_refs.values(), default=0) + 1
|
|
198
|
-
|
|
199
|
-
for assistant_tool_info in messages:
|
|
200
|
-
assistant_messages = assistant_tool_info["responses"]
|
|
201
|
-
|
|
202
|
-
for sequence_number in sorted(assistant_messages):
|
|
203
|
-
message = assistant_messages[sequence_number]
|
|
204
|
-
|
|
205
|
-
references = message["references"]
|
|
206
|
-
if len(references) == 0:
|
|
207
|
-
logger.debug(
|
|
208
|
-
"Message from assistant %s with sequence number %s does not contain any references",
|
|
209
|
-
assistant_tool_info["display_name"],
|
|
210
|
-
sequence_number,
|
|
211
|
-
)
|
|
212
|
-
continue
|
|
213
|
-
|
|
214
|
-
references = list(sorted(references, key=lambda ref: ref["sequenceNumber"]))
|
|
215
|
-
ref_map = {}
|
|
216
|
-
message_new_refs = []
|
|
217
|
-
|
|
218
|
-
for reference in references:
|
|
219
|
-
source_id = reference["sourceId"]
|
|
220
|
-
if source_id not in existing_refs:
|
|
221
|
-
message_new_refs.append(reference)
|
|
222
|
-
existing_refs[source_id] = start_index
|
|
223
|
-
start_index += 1
|
|
224
|
-
|
|
225
|
-
reference_num = existing_refs[source_id]
|
|
226
|
-
ref_map[reference["sequenceNumber"]] = reference_num
|
|
227
|
-
reference["sequenceNumber"] = reference_num
|
|
228
|
-
|
|
229
|
-
message["text"] = _replace_references_in_text(message["text"], ref_map)
|
|
230
|
-
message["references"] = message_new_refs
|