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
unique_toolkit/__init__.py
CHANGED
|
@@ -2,14 +2,27 @@
|
|
|
2
2
|
from unique_toolkit.chat import ChatService
|
|
3
3
|
from unique_toolkit.content import ContentService
|
|
4
4
|
from unique_toolkit.embedding import EmbeddingService
|
|
5
|
+
from unique_toolkit.framework_utilities.openai.client import (
|
|
6
|
+
get_async_openai_client,
|
|
7
|
+
get_openai_client,
|
|
8
|
+
)
|
|
5
9
|
from unique_toolkit.language_model import (
|
|
6
10
|
LanguageModelMessages,
|
|
7
11
|
LanguageModelName,
|
|
8
12
|
LanguageModelService,
|
|
9
13
|
LanguageModelToolDescription,
|
|
10
14
|
)
|
|
15
|
+
from unique_toolkit.services.knowledge_base import KnowledgeBaseService
|
|
11
16
|
from unique_toolkit.short_term_memory import ShortTermMemoryService
|
|
12
17
|
|
|
18
|
+
# Conditionally import langchain utilities if langchain is installed
|
|
19
|
+
try:
|
|
20
|
+
from unique_toolkit.framework_utilities.langchain.client import get_langchain_client # noqa: F401, I001
|
|
21
|
+
|
|
22
|
+
_LANGCHAIN_AVAILABLE = True
|
|
23
|
+
except ImportError:
|
|
24
|
+
_LANGCHAIN_AVAILABLE = False
|
|
25
|
+
|
|
13
26
|
# You can add other classes you frequently use here as well
|
|
14
27
|
|
|
15
28
|
__all__ = [
|
|
@@ -21,4 +34,11 @@ __all__ = [
|
|
|
21
34
|
"ContentService",
|
|
22
35
|
"EmbeddingService",
|
|
23
36
|
"ShortTermMemoryService",
|
|
37
|
+
"KnowledgeBaseService",
|
|
38
|
+
"get_openai_client",
|
|
39
|
+
"get_async_openai_client",
|
|
24
40
|
]
|
|
41
|
+
|
|
42
|
+
# Add langchain-specific exports if available
|
|
43
|
+
if _LANGCHAIN_AVAILABLE:
|
|
44
|
+
__all__.append("get_langchain_client")
|
|
@@ -4,7 +4,7 @@ from logging import Logger
|
|
|
4
4
|
from typing import Any, Generic
|
|
5
5
|
|
|
6
6
|
import jinja2
|
|
7
|
-
from pydantic import BaseModel
|
|
7
|
+
from pydantic import BaseModel, ValidationError
|
|
8
8
|
|
|
9
9
|
from unique_toolkit._common.endpoint_builder import (
|
|
10
10
|
ApiOperationProtocol,
|
|
@@ -15,10 +15,14 @@ from unique_toolkit._common.endpoint_builder import (
|
|
|
15
15
|
ResponseType,
|
|
16
16
|
)
|
|
17
17
|
from unique_toolkit._common.endpoint_requestor import (
|
|
18
|
+
RequestContext,
|
|
18
19
|
RequestorType,
|
|
19
20
|
build_requestor,
|
|
20
21
|
)
|
|
21
|
-
from unique_toolkit._common.pydantic_helpers import
|
|
22
|
+
from unique_toolkit._common.pydantic_helpers import (
|
|
23
|
+
create_complement_model,
|
|
24
|
+
create_union_model,
|
|
25
|
+
)
|
|
22
26
|
from unique_toolkit._common.string_utilities import (
|
|
23
27
|
dict_to_markdown_table,
|
|
24
28
|
extract_dicts_from_string,
|
|
@@ -37,11 +41,13 @@ NEXT_USER_MESSAGE_JINJA2_TEMPLATE = jinja2.Template("""I confirm the api call wi
|
|
|
37
41
|
```""")
|
|
38
42
|
|
|
39
43
|
|
|
40
|
-
ASSISTANT_CONFIRMATION_MESSAGE_JINJA2_TEMPLATE = jinja2.Template(
|
|
41
|
-
|
|
44
|
+
ASSISTANT_CONFIRMATION_MESSAGE_JINJA2_TEMPLATE = jinja2.Template(
|
|
45
|
+
"""
|
|
46
|
+
\n
|
|
42
47
|
{{ api_call_as_markdown_table }}
|
|
43
|
-
|
|
44
|
-
[{{ button_text }}](https://prompt={{ next_user_message | urlencode }})"""
|
|
48
|
+
\n\n
|
|
49
|
+
[{{ button_text }}](https://prompt={{ next_user_message | urlencode }})"""
|
|
50
|
+
)
|
|
45
51
|
|
|
46
52
|
|
|
47
53
|
class HumanVerificationManagerForApiCalling(
|
|
@@ -77,24 +83,67 @@ class HumanVerificationManagerForApiCalling(
|
|
|
77
83
|
]
|
|
78
84
|
],
|
|
79
85
|
requestor_type: RequestorType = RequestorType.REQUESTS,
|
|
86
|
+
environment_payload_params: BaseModel | None = None,
|
|
87
|
+
modifiable_payload_params_model: type[BaseModel] | None = None,
|
|
80
88
|
**kwargs: dict[str, Any],
|
|
81
89
|
):
|
|
90
|
+
"""
|
|
91
|
+
Manages human verification for api calling.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
logger: The logger to use for logging.
|
|
95
|
+
operation: The operation to use for the api calling.
|
|
96
|
+
requestor_type: The requestor type to use for the api calling.
|
|
97
|
+
environment_payload_params: The environment payload params to use for the api calling.
|
|
98
|
+
If None, the modifiable params model will be the operation payload model.
|
|
99
|
+
This can be useful for parameters in the payload that should not be modified by the user.
|
|
100
|
+
modifiable_payload_params_model: The modifiable payload params model to use for the api calling.
|
|
101
|
+
If None, a complement model will be created using the operation payload model
|
|
102
|
+
and the environment payload params.
|
|
103
|
+
If provided, it will be used instead of the complement model.
|
|
104
|
+
This is necessary if the modifiable params model is required
|
|
105
|
+
to use custom validators or serializers.
|
|
106
|
+
**kwargs: Additional keyword arguments to pass to the requestor.
|
|
107
|
+
"""
|
|
82
108
|
self._logger = logger
|
|
83
109
|
self._operation = operation
|
|
84
|
-
|
|
110
|
+
self._environment_payload_params = environment_payload_params
|
|
85
111
|
# Create internal models for this manager instance
|
|
86
112
|
|
|
87
|
-
|
|
113
|
+
if self._environment_payload_params is None:
|
|
114
|
+
self._modifiable_payload_params_model = self._operation.payload_model()
|
|
115
|
+
else:
|
|
116
|
+
if modifiable_payload_params_model is None:
|
|
117
|
+
self._modifiable_payload_params_model = create_complement_model(
|
|
118
|
+
model_type_a=self._operation.payload_model(),
|
|
119
|
+
model_type_b=type(self._environment_payload_params),
|
|
120
|
+
)
|
|
121
|
+
else:
|
|
122
|
+
# This is necessary if the modifiable params model is required
|
|
123
|
+
# to use custom validators or serializers.
|
|
124
|
+
self._modifiable_payload_params_model = modifiable_payload_params_model
|
|
125
|
+
|
|
126
|
+
if self._environment_payload_params is not None:
|
|
127
|
+
combined_keys = set(
|
|
128
|
+
self._modifiable_payload_params_model.model_fields.keys()
|
|
129
|
+
) | set(type(self._environment_payload_params).model_fields.keys())
|
|
130
|
+
payload_keys = set(self._operation.payload_model().model_fields.keys())
|
|
131
|
+
if not payload_keys.issubset(combined_keys):
|
|
132
|
+
raise ValueError(
|
|
133
|
+
"The modifiable params model + the environment parameters do not have all the keys of the operation payload model."
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
class VerificationModel(BaseModel):
|
|
88
137
|
confirmation: HumanConfirmation
|
|
89
|
-
|
|
138
|
+
modifiable_params: self._modifiable_payload_params_model # type: ignore
|
|
90
139
|
|
|
91
|
-
self.
|
|
140
|
+
self._verification_model = VerificationModel
|
|
92
141
|
|
|
142
|
+
self._requestor_type = requestor_type
|
|
93
143
|
self._combined_params_model = create_union_model(
|
|
94
144
|
model_type_a=self._operation.path_params_model(),
|
|
95
145
|
model_type_b=self._operation.payload_model(),
|
|
96
146
|
)
|
|
97
|
-
self._requestor_type = requestor_type
|
|
98
147
|
self._requestor = build_requestor(
|
|
99
148
|
requestor_type=requestor_type,
|
|
100
149
|
operation_type=operation,
|
|
@@ -103,7 +152,10 @@ class HumanVerificationManagerForApiCalling(
|
|
|
103
152
|
)
|
|
104
153
|
|
|
105
154
|
def detect_api_calls_from_user_message(
|
|
106
|
-
self,
|
|
155
|
+
self,
|
|
156
|
+
*,
|
|
157
|
+
last_assistant_message: ChatMessage,
|
|
158
|
+
user_message: str,
|
|
107
159
|
) -> PayloadType | None:
|
|
108
160
|
user_message_dicts = extract_dicts_from_string(user_message)
|
|
109
161
|
if len(user_message_dicts) == 0:
|
|
@@ -113,13 +165,22 @@ class HumanVerificationManagerForApiCalling(
|
|
|
113
165
|
for user_message_dict in user_message_dicts:
|
|
114
166
|
try:
|
|
115
167
|
# Convert dict to payload model first, then create payload
|
|
116
|
-
|
|
168
|
+
verfication_data = self._verification_model.model_validate(
|
|
117
169
|
user_message_dict, by_alias=True, by_name=True
|
|
118
170
|
)
|
|
119
171
|
if self._verify_human_verification(
|
|
120
|
-
|
|
172
|
+
verfication_data.confirmation, last_assistant_message
|
|
121
173
|
):
|
|
122
|
-
|
|
174
|
+
payload_dict = verfication_data.modifiable_params.model_dump()
|
|
175
|
+
if self._environment_payload_params is not None:
|
|
176
|
+
payload_dict.update(
|
|
177
|
+
self._environment_payload_params.model_dump()
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
return self._operation.payload_model().model_validate(
|
|
181
|
+
payload_dict, by_alias=True, by_name=True
|
|
182
|
+
)
|
|
183
|
+
|
|
123
184
|
except Exception as e:
|
|
124
185
|
self._logger.error(f"Error detecting api calls from user message: {e}")
|
|
125
186
|
|
|
@@ -140,11 +201,29 @@ class HumanVerificationManagerForApiCalling(
|
|
|
140
201
|
return confirmation.payload_hash in last_assistant_message.content
|
|
141
202
|
|
|
142
203
|
def _create_next_user_message(self, payload: PayloadType) -> str:
|
|
143
|
-
|
|
144
|
-
|
|
204
|
+
# Extract only the modifiable fields from the payload
|
|
205
|
+
payload_dict = payload.model_dump()
|
|
206
|
+
if self._environment_payload_params is not None:
|
|
207
|
+
# Remove environment params from payload to avoid validation errors
|
|
208
|
+
environment_fields = set(
|
|
209
|
+
type(self._environment_payload_params).model_fields.keys()
|
|
210
|
+
)
|
|
211
|
+
modifiable_dict = {
|
|
212
|
+
k: v for k, v in payload_dict.items() if k not in environment_fields
|
|
213
|
+
}
|
|
214
|
+
else:
|
|
215
|
+
modifiable_dict = payload_dict
|
|
216
|
+
|
|
217
|
+
modifiable_params = self._modifiable_payload_params_model.model_validate(
|
|
218
|
+
modifiable_dict,
|
|
219
|
+
by_alias=True,
|
|
220
|
+
by_name=True,
|
|
221
|
+
)
|
|
222
|
+
api_call = self._verification_model(
|
|
223
|
+
modifiable_params=modifiable_params,
|
|
145
224
|
confirmation=HumanConfirmation(
|
|
146
225
|
payload_hash=hashlib.sha256(
|
|
147
|
-
|
|
226
|
+
modifiable_params.model_dump_json().encode()
|
|
148
227
|
).hexdigest(),
|
|
149
228
|
time_stamp=datetime.now(),
|
|
150
229
|
),
|
|
@@ -153,28 +232,42 @@ class HumanVerificationManagerForApiCalling(
|
|
|
153
232
|
api_call_as_json=api_call.model_dump_json(indent=2)
|
|
154
233
|
)
|
|
155
234
|
|
|
156
|
-
def create_assistant_confirmation_message(
|
|
235
|
+
def create_assistant_confirmation_message(
|
|
236
|
+
self, *, payload: PayloadType, button_text: str = "Confirm"
|
|
237
|
+
) -> str:
|
|
157
238
|
return ASSISTANT_CONFIRMATION_MESSAGE_JINJA2_TEMPLATE.render(
|
|
158
239
|
api_call_as_markdown_table=dict_to_markdown_table(payload.model_dump()),
|
|
159
|
-
button_text=
|
|
240
|
+
button_text=button_text,
|
|
160
241
|
next_user_message=self._create_next_user_message(payload),
|
|
161
242
|
)
|
|
162
243
|
|
|
163
244
|
def call_api(
|
|
164
245
|
self,
|
|
165
246
|
*,
|
|
166
|
-
|
|
247
|
+
context: RequestContext,
|
|
167
248
|
path_params: PathParamsType,
|
|
168
249
|
payload: PayloadType,
|
|
169
250
|
) -> ResponseType:
|
|
251
|
+
"""
|
|
252
|
+
Call the api with the given path params, payload and secured payload params.
|
|
253
|
+
|
|
254
|
+
The `secured payload params` are params that are enforced by the application.
|
|
255
|
+
It should generally be not possible for the user to adapt those but here we
|
|
256
|
+
ensure that the application has the last word.
|
|
257
|
+
|
|
258
|
+
"""
|
|
170
259
|
params = path_params.model_dump()
|
|
171
260
|
params.update(payload.model_dump())
|
|
172
261
|
|
|
173
262
|
response = self._requestor.request(
|
|
174
|
-
|
|
263
|
+
context=context,
|
|
175
264
|
**params,
|
|
176
265
|
)
|
|
177
|
-
|
|
266
|
+
try:
|
|
267
|
+
return self._operation.handle_response(response)
|
|
268
|
+
except ValidationError as e:
|
|
269
|
+
self._logger.error(f"Error calling api: {e}. Response: {response}")
|
|
270
|
+
raise e
|
|
178
271
|
|
|
179
272
|
|
|
180
273
|
if __name__ == "__main__":
|
|
@@ -199,9 +292,9 @@ if __name__ == "__main__":
|
|
|
199
292
|
class CombinedParams(GetUserPathParams, GetUserRequestBody):
|
|
200
293
|
pass
|
|
201
294
|
|
|
202
|
-
|
|
295
|
+
UserApiOperation = build_api_operation(
|
|
203
296
|
method=EndpointMethods.GET,
|
|
204
|
-
|
|
297
|
+
path_template=Template("/users/{user_id}"),
|
|
205
298
|
path_params_constructor=GetUserPathParams,
|
|
206
299
|
payload_constructor=GetUserRequestBody,
|
|
207
300
|
response_model_type=UserResponse,
|
|
@@ -209,15 +302,15 @@ if __name__ == "__main__":
|
|
|
209
302
|
|
|
210
303
|
human_verification_manager = HumanVerificationManagerForApiCalling(
|
|
211
304
|
logger=logging.getLogger(__name__),
|
|
212
|
-
operation=
|
|
305
|
+
operation=UserApiOperation,
|
|
213
306
|
requestor_type=RequestorType.FAKE,
|
|
214
307
|
return_value={"id": 100, "name": "John Doe"},
|
|
215
308
|
)
|
|
216
309
|
|
|
217
310
|
payload = GetUserRequestBody(include_profile=True)
|
|
218
311
|
|
|
219
|
-
api_call = human_verification_manager.
|
|
220
|
-
|
|
312
|
+
api_call = human_verification_manager._verification_model(
|
|
313
|
+
modifiable_params=payload,
|
|
221
314
|
confirmation=HumanConfirmation(
|
|
222
315
|
payload_hash=hashlib.sha256(payload.model_dump_json().encode()).hexdigest(),
|
|
223
316
|
time_stamp=datetime.now(),
|
|
@@ -2,12 +2,12 @@ from typing import Annotated, Any
|
|
|
2
2
|
|
|
3
3
|
from pydantic import BaseModel, Field
|
|
4
4
|
|
|
5
|
-
from unique_toolkit._common.default_language_model import DEFAULT_GPT_35_TURBO
|
|
6
5
|
from unique_toolkit._common.validators import LMI, get_LMI_default_field
|
|
7
6
|
from unique_toolkit.agentic.evaluation.context_relevancy.schema import (
|
|
8
7
|
StructuredOutputConfig,
|
|
9
8
|
)
|
|
10
9
|
from unique_toolkit.agentic.tools.config import get_configuration_dict
|
|
10
|
+
from unique_toolkit.language_model.default_language_model import DEFAULT_GPT_4o
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class ChunkRelevancySortConfig(BaseModel):
|
|
@@ -25,11 +25,11 @@ class ChunkRelevancySortConfig(BaseModel):
|
|
|
25
25
|
description="The relevancy level order.",
|
|
26
26
|
)
|
|
27
27
|
language_model: LMI = get_LMI_default_field(
|
|
28
|
-
|
|
28
|
+
DEFAULT_GPT_4o,
|
|
29
29
|
description="The language model to use for the chunk relevancy sort.",
|
|
30
30
|
)
|
|
31
31
|
fallback_language_model: LMI = get_LMI_default_field(
|
|
32
|
-
|
|
32
|
+
DEFAULT_GPT_4o,
|
|
33
33
|
description="The language model to use as a fallback.",
|
|
34
34
|
)
|
|
35
35
|
additional_llm_options: dict[str, Any] = Field(
|
|
@@ -13,10 +13,6 @@ from unique_toolkit._common.chunk_relevancy_sorter.schemas import (
|
|
|
13
13
|
ChunkRelevancySorterResult,
|
|
14
14
|
)
|
|
15
15
|
from unique_toolkit._common.chunk_relevancy_sorter.service import ChunkRelevancySorter
|
|
16
|
-
from unique_toolkit._common.default_language_model import (
|
|
17
|
-
DEFAULT_GPT_35_TURBO,
|
|
18
|
-
DEFAULT_GPT_4o,
|
|
19
|
-
)
|
|
20
16
|
from unique_toolkit.agentic.evaluation.context_relevancy.schema import (
|
|
21
17
|
StructuredOutputConfig,
|
|
22
18
|
)
|
|
@@ -26,6 +22,7 @@ from unique_toolkit.agentic.evaluation.schemas import (
|
|
|
26
22
|
)
|
|
27
23
|
from unique_toolkit.app.schemas import ChatEvent
|
|
28
24
|
from unique_toolkit.content.schemas import ContentChunk
|
|
25
|
+
from unique_toolkit.language_model.default_language_model import DEFAULT_GPT_4o
|
|
29
26
|
from unique_toolkit.language_model.infos import LanguageModelInfo
|
|
30
27
|
|
|
31
28
|
|
|
@@ -60,7 +57,7 @@ def config():
|
|
|
60
57
|
relevancy_levels_to_consider=["high", "medium", "low"],
|
|
61
58
|
relevancy_level_order={"high": 0, "medium": 1, "low": 2},
|
|
62
59
|
language_model=LanguageModelInfo.from_name(DEFAULT_GPT_4o),
|
|
63
|
-
fallback_language_model=LanguageModelInfo.from_name(
|
|
60
|
+
fallback_language_model=LanguageModelInfo.from_name(DEFAULT_GPT_4o),
|
|
64
61
|
structured_output_config=StructuredOutputConfig(
|
|
65
62
|
enabled=False,
|
|
66
63
|
extract_fact_list=False,
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import warnings
|
|
2
|
+
|
|
1
3
|
from unique_toolkit.language_model.infos import LanguageModelName
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
warnings.warn(
|
|
6
|
+
"unique_toolkit._common.default_language_model is deprecated. "
|
|
7
|
+
"Import DEFAULT_GPT_4o from unique_toolkit.language_model instead.",
|
|
8
|
+
DeprecationWarning,
|
|
9
|
+
stacklevel=2,
|
|
10
|
+
)
|
|
11
|
+
|
|
4
12
|
DEFAULT_GPT_4o = LanguageModelName.AZURE_GPT_4o_2024_1120
|
|
5
|
-
DEFAULT_GPT_4o_STRUCTURED_OUTPUT = LanguageModelName.AZURE_GPT_4o_2024_0806
|
|
6
|
-
DEFAULT_GPT_4o_MINI = LanguageModelName.AZURE_GPT_4o_MINI_2024_0718
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
from pydantic import BaseModel, Field
|
|
2
|
+
|
|
3
|
+
from unique_toolkit._common.pydantic_helpers import get_configuration_dict
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DocxGeneratorConfig(BaseModel):
|
|
7
|
+
model_config = get_configuration_dict()
|
|
8
|
+
|
|
9
|
+
template_content_id: str = Field(
|
|
10
|
+
default="",
|
|
11
|
+
description="The content id of the template file uploaded to the knowledge base.",
|
|
12
|
+
)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
from docx.document import Document as DocumentObject
|
|
2
|
+
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
|
|
3
|
+
from docxtpl import DocxTemplate
|
|
4
|
+
from pydantic import BaseModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class HeadingField(BaseModel):
|
|
8
|
+
text: str
|
|
9
|
+
level: int = 4
|
|
10
|
+
alignment: WD_PARAGRAPH_ALIGNMENT = WD_PARAGRAPH_ALIGNMENT.LEFT
|
|
11
|
+
|
|
12
|
+
def add(self, doc: DocumentObject):
|
|
13
|
+
p = doc.add_heading(self.text, level=self.level)
|
|
14
|
+
p.alignment = self.alignment
|
|
15
|
+
return p
|
|
16
|
+
|
|
17
|
+
def __str__(self):
|
|
18
|
+
return f"HeadingField(text={self.text}, level={self.level}, alignment={self.alignment})"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ParagraphField(BaseModel):
|
|
22
|
+
text: str
|
|
23
|
+
style: str | None = None
|
|
24
|
+
alignment: WD_PARAGRAPH_ALIGNMENT = WD_PARAGRAPH_ALIGNMENT.LEFT
|
|
25
|
+
|
|
26
|
+
def add(self, doc: DocumentObject):
|
|
27
|
+
p = doc.add_paragraph(self.text, style=self.style)
|
|
28
|
+
p.alignment = self.alignment
|
|
29
|
+
return p
|
|
30
|
+
|
|
31
|
+
def __str__(self):
|
|
32
|
+
return f"ParagraphField(text={self.text}, style={self.style}, alignment={self.alignment})"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class RunField(BaseModel):
|
|
36
|
+
text: str
|
|
37
|
+
italic: bool | None = False
|
|
38
|
+
bold: bool | None = False
|
|
39
|
+
alignment: WD_PARAGRAPH_ALIGNMENT = WD_PARAGRAPH_ALIGNMENT.LEFT
|
|
40
|
+
|
|
41
|
+
def __str__(self):
|
|
42
|
+
return f"RunField(text={self.text}, italic={self.italic}, alignment={self.alignment})"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class RunsField(BaseModel):
|
|
46
|
+
runs: list[RunField]
|
|
47
|
+
style: str | None = None
|
|
48
|
+
alignment: WD_PARAGRAPH_ALIGNMENT = WD_PARAGRAPH_ALIGNMENT.LEFT
|
|
49
|
+
|
|
50
|
+
def add(self, doc: DocumentObject):
|
|
51
|
+
if not self.runs:
|
|
52
|
+
return None
|
|
53
|
+
p = doc.add_paragraph(style=self.style)
|
|
54
|
+
for run in self.runs:
|
|
55
|
+
r = p.add_run(run.text)
|
|
56
|
+
if run.italic:
|
|
57
|
+
r.italic = True
|
|
58
|
+
if run.bold:
|
|
59
|
+
r.bold = True
|
|
60
|
+
return p
|
|
61
|
+
|
|
62
|
+
def __str__(self):
|
|
63
|
+
return f"RunsField(runs={self.runs}, style={self.style}, alignment={self.alignment})"
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class ContentField(BaseModel):
|
|
67
|
+
contents: list[HeadingField | ParagraphField | RunsField]
|
|
68
|
+
|
|
69
|
+
def add(self, doc: DocxTemplate):
|
|
70
|
+
sd = doc.new_subdoc()
|
|
71
|
+
for content in self.contents:
|
|
72
|
+
# if isinstance(content, ImageField):
|
|
73
|
+
# content.download_image(self.download_path)
|
|
74
|
+
# content.add(sd) # type: ignore
|
|
75
|
+
# else:
|
|
76
|
+
content.add(sd) # type: ignore
|
|
77
|
+
return sd
|
|
78
|
+
|
|
79
|
+
def __str__(self):
|
|
80
|
+
return f"ContentField(contents={self.contents})"
|