unique_toolkit 0.8.18__py3-none-any.whl → 0.8.19__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.
- unique_toolkit/_common/default_language_model.py +1 -1
- unique_toolkit/_common/token/token_counting.py +9 -20
- unique_toolkit/_common/validators.py +2 -3
- unique_toolkit/debug_info_manager/debug_info_manager.py +0 -1
- unique_toolkit/evals/config.py +0 -1
- unique_toolkit/evals/context_relevancy/schema.py +1 -6
- unique_toolkit/evals/context_relevancy/service.py +13 -13
- unique_toolkit/evals/evaluation_manager.py +10 -12
- unique_toolkit/evals/hallucination/constants.py +0 -1
- unique_toolkit/evals/hallucination/hallucination_evaluation.py +5 -8
- unique_toolkit/evals/hallucination/service.py +0 -1
- unique_toolkit/evals/hallucination/utils.py +7 -8
- unique_toolkit/evals/output_parser.py +1 -1
- unique_toolkit/evals/schemas.py +2 -1
- unique_toolkit/evals/tests/test_context_relevancy_service.py +10 -9
- unique_toolkit/evals/tests/test_output_parser.py +8 -4
- unique_toolkit/history_manager/history_construction_with_contents.py +10 -20
- unique_toolkit/history_manager/history_manager.py +11 -22
- unique_toolkit/history_manager/loop_token_reducer.py +121 -109
- unique_toolkit/history_manager/utils.py +0 -1
- unique_toolkit/language_model/infos.py +1 -1
- unique_toolkit/language_model/schemas.py +0 -1
- unique_toolkit/postprocessor/postprocessor_manager.py +1 -3
- unique_toolkit/reference_manager/reference_manager.py +3 -4
- unique_toolkit/short_term_memory/persistent_short_term_memory_manager.py +2 -1
- unique_toolkit/thinking_manager/thinking_manager.py +2 -1
- unique_toolkit/tools/config.py +4 -5
- unique_toolkit/tools/factory.py +2 -8
- unique_toolkit/tools/schemas.py +1 -1
- unique_toolkit/tools/test/test_tool_progress_reporter.py +1 -0
- unique_toolkit/tools/tool.py +3 -7
- unique_toolkit/tools/tool_manager.py +3 -2
- unique_toolkit/tools/tool_progress_reporter.py +1 -0
- unique_toolkit/tools/utils/source_handling/schema.py +0 -1
- unique_toolkit/tools/utils/source_handling/tests/test_source_formatting.py +1 -0
- {unique_toolkit-0.8.18.dist-info → unique_toolkit-0.8.19.dist-info}/METADATA +5 -1
- {unique_toolkit-0.8.18.dist-info → unique_toolkit-0.8.19.dist-info}/RECORD +39 -39
- {unique_toolkit-0.8.18.dist-info → unique_toolkit-0.8.19.dist-info}/LICENSE +0 -0
- {unique_toolkit-0.8.18.dist-info → unique_toolkit-0.8.19.dist-info}/WHEEL +0 -0
|
@@ -1,18 +1,31 @@
|
|
|
1
|
-
|
|
2
1
|
import json
|
|
3
2
|
from logging import Logger
|
|
4
3
|
from typing import Awaitable, Callable
|
|
5
4
|
|
|
6
|
-
from pydantic import BaseModel
|
|
7
5
|
import tiktoken
|
|
8
|
-
from
|
|
6
|
+
from pydantic import BaseModel
|
|
7
|
+
|
|
8
|
+
from unique_toolkit._common.token.token_counting import (
|
|
9
|
+
num_token_for_language_model_messages,
|
|
10
|
+
)
|
|
9
11
|
from unique_toolkit._common.validators import LMI
|
|
10
12
|
from unique_toolkit.app.schemas import ChatEvent
|
|
11
13
|
from unique_toolkit.chat.service import ChatService
|
|
12
14
|
from unique_toolkit.content.schemas import ContentChunk
|
|
13
15
|
from unique_toolkit.content.service import ContentService
|
|
14
|
-
from unique_toolkit.history_manager.history_construction_with_contents import
|
|
15
|
-
|
|
16
|
+
from unique_toolkit.history_manager.history_construction_with_contents import (
|
|
17
|
+
FileContentSerialization,
|
|
18
|
+
get_full_history_with_contents,
|
|
19
|
+
)
|
|
20
|
+
from unique_toolkit.language_model.schemas import (
|
|
21
|
+
LanguageModelAssistantMessage,
|
|
22
|
+
LanguageModelMessage,
|
|
23
|
+
LanguageModelMessageRole,
|
|
24
|
+
LanguageModelMessages,
|
|
25
|
+
LanguageModelSystemMessage,
|
|
26
|
+
LanguageModelToolMessage,
|
|
27
|
+
LanguageModelUserMessage,
|
|
28
|
+
)
|
|
16
29
|
from unique_toolkit.reference_manager.reference_manager import ReferenceManager
|
|
17
30
|
|
|
18
31
|
|
|
@@ -26,18 +39,16 @@ class SourceReductionResult(BaseModel):
|
|
|
26
39
|
arbitrary_types_allowed = True
|
|
27
40
|
|
|
28
41
|
|
|
29
|
-
class LoopTokenReducer
|
|
30
|
-
|
|
42
|
+
class LoopTokenReducer:
|
|
31
43
|
def __init__(
|
|
32
44
|
self,
|
|
33
45
|
logger: Logger,
|
|
34
46
|
event: ChatEvent,
|
|
35
|
-
max_history_tokens:int,
|
|
47
|
+
max_history_tokens: int,
|
|
36
48
|
has_uploaded_content_config: bool,
|
|
37
49
|
reference_manager: ReferenceManager,
|
|
38
|
-
language_model: LMI
|
|
50
|
+
language_model: LMI,
|
|
39
51
|
):
|
|
40
|
-
|
|
41
52
|
self._max_history_tokens = max_history_tokens
|
|
42
53
|
self._has_uploaded_content_config = has_uploaded_content_config
|
|
43
54
|
self._logger = logger
|
|
@@ -48,29 +59,28 @@ class LoopTokenReducer():
|
|
|
48
59
|
self._content_service = ContentService.from_event(event)
|
|
49
60
|
self._user_message = event.payload.user_message
|
|
50
61
|
self._chat_id = event.payload.chat_id
|
|
51
|
-
|
|
52
62
|
|
|
53
63
|
def _get_encoder(self, language_model: LMI) -> tiktoken.Encoding:
|
|
54
64
|
name = language_model.encoder_name or "cl100k_base"
|
|
55
65
|
return tiktoken.get_encoding(name)
|
|
56
66
|
|
|
57
|
-
async def get_history_for_model_call(
|
|
67
|
+
async def get_history_for_model_call(
|
|
68
|
+
self,
|
|
58
69
|
original_user_message: str,
|
|
59
70
|
rendered_user_message_string: str,
|
|
60
71
|
rendered_system_message_string: str,
|
|
61
72
|
loop_history: list[LanguageModelMessage],
|
|
62
|
-
remove_from_text: Callable[[str], Awaitable[str]]
|
|
63
|
-
|
|
73
|
+
remove_from_text: Callable[[str], Awaitable[str]],
|
|
74
|
+
) -> LanguageModelMessages:
|
|
64
75
|
"""Compose the system and user messages for the plan execution step, which is evaluating if any further tool calls are required."""
|
|
65
76
|
|
|
66
|
-
|
|
67
77
|
messages = await self._construct_history(
|
|
68
78
|
original_user_message,
|
|
69
79
|
rendered_user_message_string,
|
|
70
80
|
rendered_system_message_string,
|
|
71
81
|
loop_history,
|
|
72
|
-
remove_from_text
|
|
73
|
-
|
|
82
|
+
remove_from_text,
|
|
83
|
+
)
|
|
74
84
|
|
|
75
85
|
token_count = self._count_message_tokens(messages)
|
|
76
86
|
self._log_token_usage(token_count)
|
|
@@ -79,11 +89,11 @@ class LoopTokenReducer():
|
|
|
79
89
|
token_count_before_reduction = token_count
|
|
80
90
|
loop_history = self._handle_token_limit_exceeded(loop_history)
|
|
81
91
|
messages = await self._construct_history(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
92
|
+
original_user_message,
|
|
93
|
+
rendered_user_message_string,
|
|
94
|
+
rendered_system_message_string,
|
|
95
|
+
loop_history,
|
|
96
|
+
remove_from_text,
|
|
87
97
|
)
|
|
88
98
|
token_count = self._count_message_tokens(messages)
|
|
89
99
|
self._log_token_usage(token_count)
|
|
@@ -92,7 +102,7 @@ class LoopTokenReducer():
|
|
|
92
102
|
break
|
|
93
103
|
|
|
94
104
|
return messages
|
|
95
|
-
|
|
105
|
+
|
|
96
106
|
def _exceeds_token_limit(self, token_count: int) -> bool:
|
|
97
107
|
"""Check if token count exceeds the maximum allowed limit and if at least one tool call has more than one source."""
|
|
98
108
|
# At least one tool call should have more than one chunk as answer
|
|
@@ -105,13 +115,11 @@ class LoopTokenReducer():
|
|
|
105
115
|
# include system_prompt and user question already
|
|
106
116
|
# TODO: There is a problem if we exceed but only have one chunk per tool call
|
|
107
117
|
exceeds_limit = (
|
|
108
|
-
token_count
|
|
109
|
-
> self._language_model.token_limits.token_limit_input
|
|
118
|
+
token_count > self._language_model.token_limits.token_limit_input
|
|
110
119
|
)
|
|
111
120
|
|
|
112
121
|
return has_multiple_chunks_for_a_tool_call and exceeds_limit
|
|
113
122
|
|
|
114
|
-
|
|
115
123
|
def _count_message_tokens(self, messages: LanguageModelMessages) -> int:
|
|
116
124
|
"""Count tokens in messages using the configured encoding model."""
|
|
117
125
|
return num_token_for_language_model_messages(
|
|
@@ -130,28 +138,34 @@ class LoopTokenReducer():
|
|
|
130
138
|
rendered_user_message_string: str,
|
|
131
139
|
rendered_system_message_string: str,
|
|
132
140
|
loop_history: list[LanguageModelMessage],
|
|
133
|
-
remove_from_text: Callable[[str], Awaitable[str]]
|
|
141
|
+
remove_from_text: Callable[[str], Awaitable[str]],
|
|
134
142
|
) -> LanguageModelMessages:
|
|
135
143
|
history_from_db = await self._get_history_from_db(remove_from_text)
|
|
136
|
-
history_from_db = self._replace_user_message(
|
|
137
|
-
|
|
144
|
+
history_from_db = self._replace_user_message(
|
|
145
|
+
history_from_db, original_user_message, rendered_user_message_string
|
|
146
|
+
)
|
|
147
|
+
system_message = LanguageModelSystemMessage(
|
|
148
|
+
content=rendered_system_message_string
|
|
149
|
+
)
|
|
138
150
|
|
|
139
151
|
constructed_history = LanguageModelMessages(
|
|
140
152
|
[system_message] + history_from_db + loop_history,
|
|
141
153
|
)
|
|
142
154
|
|
|
143
|
-
|
|
144
155
|
return constructed_history
|
|
145
|
-
|
|
146
156
|
|
|
147
|
-
def _handle_token_limit_exceeded(
|
|
157
|
+
def _handle_token_limit_exceeded(
|
|
158
|
+
self, loop_history: list[LanguageModelMessage]
|
|
159
|
+
) -> list[LanguageModelMessage]:
|
|
148
160
|
"""Handle case where token limit is exceeded by reducing sources in tool responses."""
|
|
149
161
|
self._logger.warning(
|
|
150
162
|
f"Length of messages is exceeds limit of {self._language_model.token_limits.token_limit_input} tokens. "
|
|
151
163
|
"Reducing number of sources per tool call.",
|
|
152
164
|
)
|
|
153
|
-
|
|
154
|
-
return self._reduce_message_length_by_reducing_sources_in_tool_response(
|
|
165
|
+
|
|
166
|
+
return self._reduce_message_length_by_reducing_sources_in_tool_response(
|
|
167
|
+
loop_history
|
|
168
|
+
)
|
|
155
169
|
|
|
156
170
|
def _replace_user_message(
|
|
157
171
|
self,
|
|
@@ -176,21 +190,24 @@ class LoopTokenReducer():
|
|
|
176
190
|
original_user_message,
|
|
177
191
|
"",
|
|
178
192
|
)
|
|
179
|
-
t["text"] =
|
|
193
|
+
t["text"] = (
|
|
194
|
+
rendered_user_message_string
|
|
195
|
+
+ added_to_message_by_history
|
|
196
|
+
)
|
|
180
197
|
break
|
|
181
198
|
elif m.content:
|
|
182
|
-
added_to_message_by_history = m.content.replace(
|
|
199
|
+
added_to_message_by_history = m.content.replace(
|
|
200
|
+
original_user_message, ""
|
|
201
|
+
)
|
|
183
202
|
m.content = rendered_user_message_string + added_to_message_by_history
|
|
184
203
|
else:
|
|
185
204
|
history = history + [
|
|
186
205
|
LanguageModelUserMessage(content=rendered_user_message_string),
|
|
187
206
|
]
|
|
188
207
|
return history
|
|
189
|
-
|
|
190
208
|
|
|
191
209
|
async def _get_history_from_db(
|
|
192
|
-
self,
|
|
193
|
-
remove_from_text: Callable[[str], Awaitable[str]]
|
|
210
|
+
self, remove_from_text: Callable[[str], Awaitable[str]]
|
|
194
211
|
) -> list[LanguageModelMessage]:
|
|
195
212
|
"""
|
|
196
213
|
Get the history of the conversation. The function will retrieve a subset of the full history based on the configuration.
|
|
@@ -199,25 +216,25 @@ class LoopTokenReducer():
|
|
|
199
216
|
list[LanguageModelMessage]: The history
|
|
200
217
|
"""
|
|
201
218
|
full_history = get_full_history_with_contents(
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
full_history.root = await self._clean_messages(
|
|
214
|
-
|
|
219
|
+
user_message=self._user_message,
|
|
220
|
+
chat_id=self._chat_id,
|
|
221
|
+
chat_service=self._chat_service,
|
|
222
|
+
content_service=self._content_service,
|
|
223
|
+
file_content_serialization_type=(
|
|
224
|
+
FileContentSerialization.NONE
|
|
225
|
+
if self._has_uploaded_content_config
|
|
226
|
+
else FileContentSerialization.FILE_NAME
|
|
227
|
+
),
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
full_history.root = await self._clean_messages(
|
|
231
|
+
full_history.root, remove_from_text
|
|
232
|
+
)
|
|
233
|
+
|
|
215
234
|
limited_history_messages = self._limit_to_token_window(
|
|
216
|
-
full_history.root,
|
|
217
|
-
self._max_history_tokens
|
|
235
|
+
full_history.root, self._max_history_tokens
|
|
218
236
|
)
|
|
219
|
-
|
|
220
|
-
|
|
237
|
+
|
|
221
238
|
if len(limited_history_messages) == 0:
|
|
222
239
|
limited_history_messages = full_history.root[-1:]
|
|
223
240
|
|
|
@@ -241,9 +258,15 @@ class LoopTokenReducer():
|
|
|
241
258
|
return selected_messages[::-1]
|
|
242
259
|
|
|
243
260
|
async def _clean_messages(
|
|
244
|
-
self,
|
|
245
|
-
messages: list[
|
|
246
|
-
|
|
261
|
+
self,
|
|
262
|
+
messages: list[
|
|
263
|
+
LanguageModelMessage
|
|
264
|
+
| LanguageModelToolMessage
|
|
265
|
+
| LanguageModelAssistantMessage
|
|
266
|
+
| LanguageModelSystemMessage
|
|
267
|
+
| LanguageModelUserMessage
|
|
268
|
+
],
|
|
269
|
+
remove_from_text: Callable[[str], Awaitable[str]],
|
|
247
270
|
) -> list[LanguageModelMessage]:
|
|
248
271
|
for message in messages:
|
|
249
272
|
if isinstance(message.content, str):
|
|
@@ -254,13 +277,12 @@ class LoopTokenReducer():
|
|
|
254
277
|
)
|
|
255
278
|
return messages
|
|
256
279
|
|
|
257
|
-
def _count_tokens(self,text:str) -> int:
|
|
258
|
-
|
|
280
|
+
def _count_tokens(self, text: str) -> int:
|
|
259
281
|
return len(self._encoder.encode(text))
|
|
260
282
|
|
|
261
283
|
def ensure_last_message_is_user_message(self, limited_history_messages):
|
|
262
284
|
"""
|
|
263
|
-
As the token limit can be reached in the middle of a gpt_request,
|
|
285
|
+
As the token limit can be reached in the middle of a gpt_request,
|
|
264
286
|
we move forward to the next user message,to avoid confusing messages for the LLM
|
|
265
287
|
"""
|
|
266
288
|
idx = 0
|
|
@@ -271,45 +293,42 @@ class LoopTokenReducer():
|
|
|
271
293
|
# FIXME: This might reduce the history by a lot if we have a lot of tool calls / references in the history. Could make sense to summarize the messages and include
|
|
272
294
|
# FIXME: We should remove chunks no longer in history from handler
|
|
273
295
|
return limited_history_messages[idx:]
|
|
274
|
-
|
|
275
296
|
|
|
276
297
|
def _reduce_message_length_by_reducing_sources_in_tool_response(
|
|
277
|
-
|
|
278
|
-
|
|
298
|
+
self,
|
|
299
|
+
history: list[LanguageModelMessage],
|
|
279
300
|
) -> list[LanguageModelMessage]:
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
301
|
+
"""
|
|
302
|
+
Reduce the message length by removing the last source result of each tool call.
|
|
303
|
+
If there is only one source for a tool call, the tool call message is returned unchanged.
|
|
304
|
+
"""
|
|
305
|
+
history_reduced: list[LanguageModelMessage] = []
|
|
306
|
+
content_chunks_reduced: list[ContentChunk] = []
|
|
307
|
+
chunk_offset = 0
|
|
308
|
+
source_offset = 0
|
|
309
|
+
|
|
310
|
+
for message in history:
|
|
311
|
+
if self._should_reduce_message(message):
|
|
312
|
+
result = self._reduce_sources_in_tool_message(
|
|
313
|
+
message, # type: ignore
|
|
314
|
+
chunk_offset,
|
|
315
|
+
source_offset,
|
|
316
|
+
)
|
|
317
|
+
content_chunks_reduced.extend(result.reduced_chunks)
|
|
318
|
+
history_reduced.append(result.message)
|
|
319
|
+
chunk_offset = result.chunk_offset
|
|
320
|
+
source_offset = result.source_offset
|
|
321
|
+
else:
|
|
322
|
+
history_reduced.append(message)
|
|
323
|
+
|
|
324
|
+
self._reference_manager.replace(chunks=content_chunks_reduced)
|
|
325
|
+
return history_reduced
|
|
326
|
+
|
|
306
327
|
def _should_reduce_message(self, message: LanguageModelMessage) -> bool:
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
)
|
|
312
|
-
|
|
328
|
+
"""Determine if a message should have its sources reduced."""
|
|
329
|
+
return message.role == LanguageModelMessageRole.TOOL and isinstance(
|
|
330
|
+
message, LanguageModelToolMessage
|
|
331
|
+
)
|
|
313
332
|
|
|
314
333
|
def _reduce_sources_in_tool_message(
|
|
315
334
|
self,
|
|
@@ -344,8 +363,7 @@ class LoopTokenReducer():
|
|
|
344
363
|
chunk_offset : chunk_offset + num_sources - 1
|
|
345
364
|
]
|
|
346
365
|
self._reference_manager.replace_chunks_of_tool(
|
|
347
|
-
message.tool_call_id,
|
|
348
|
-
reduced_chunks
|
|
366
|
+
message.tool_call_id, reduced_chunks
|
|
349
367
|
)
|
|
350
368
|
|
|
351
369
|
# Create new message with reduced sources
|
|
@@ -359,11 +377,9 @@ class LoopTokenReducer():
|
|
|
359
377
|
message=new_message,
|
|
360
378
|
reduced_chunks=content_chunks_reduced,
|
|
361
379
|
chunk_offset=chunk_offset + num_sources,
|
|
362
|
-
source_offset=source_offset
|
|
363
|
-
+ num_sources
|
|
364
|
-
- (1 if num_sources != 1 else 0),
|
|
380
|
+
source_offset=source_offset + num_sources - (1 if num_sources != 1 else 0),
|
|
365
381
|
)
|
|
366
|
-
|
|
382
|
+
|
|
367
383
|
def _create_tool_call_message_with_reduced_sources(
|
|
368
384
|
self,
|
|
369
385
|
message: LanguageModelToolMessage,
|
|
@@ -384,7 +400,7 @@ class LoopTokenReducer():
|
|
|
384
400
|
return self._create_reduced_standard_sources_message(
|
|
385
401
|
message, content_chunks, source_offset
|
|
386
402
|
)
|
|
387
|
-
|
|
403
|
+
|
|
388
404
|
def _create_reduced_table_search_message(
|
|
389
405
|
self,
|
|
390
406
|
message: LanguageModelToolMessage,
|
|
@@ -405,9 +421,7 @@ class LoopTokenReducer():
|
|
|
405
421
|
elif isinstance(message.content, dict):
|
|
406
422
|
content_dict = message.content
|
|
407
423
|
else:
|
|
408
|
-
raise ValueError(
|
|
409
|
-
f"Unexpected content type: {type(message.content)}"
|
|
410
|
-
)
|
|
424
|
+
raise ValueError(f"Unexpected content type: {type(message.content)}")
|
|
411
425
|
|
|
412
426
|
content = json.dumps(
|
|
413
427
|
{
|
|
@@ -422,7 +436,6 @@ class LoopTokenReducer():
|
|
|
422
436
|
name=message.name,
|
|
423
437
|
)
|
|
424
438
|
|
|
425
|
-
|
|
426
439
|
def _create_reduced_empty_sources_message(
|
|
427
440
|
self,
|
|
428
441
|
message: LanguageModelToolMessage,
|
|
@@ -434,7 +447,6 @@ class LoopTokenReducer():
|
|
|
434
447
|
name=message.name,
|
|
435
448
|
)
|
|
436
449
|
|
|
437
|
-
|
|
438
450
|
def _create_reduced_standard_sources_message(
|
|
439
451
|
self,
|
|
440
452
|
message: LanguageModelToolMessage,
|
|
@@ -136,7 +136,6 @@ class LanguageModelStreamResponse(BaseModel):
|
|
|
136
136
|
"""
|
|
137
137
|
return not self.message.original_text and not self.tool_calls
|
|
138
138
|
|
|
139
|
-
|
|
140
139
|
def to_openai_param(self) -> ChatCompletionAssistantMessageParam:
|
|
141
140
|
return ChatCompletionAssistantMessageParam(
|
|
142
141
|
role="assistant",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
from abc import ABC
|
|
2
1
|
import asyncio
|
|
2
|
+
from abc import ABC
|
|
3
3
|
from logging import Logger
|
|
4
4
|
|
|
5
5
|
from unique_toolkit.chat.service import ChatService
|
|
@@ -52,8 +52,6 @@ class PostprocessorManager:
|
|
|
52
52
|
The PostprocessorManager serves as a centralized system for managing and applying postprocessing logic to enhance response quality and consistency.
|
|
53
53
|
"""
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
57
55
|
def __init__(
|
|
58
56
|
self,
|
|
59
57
|
logger: Logger,
|
|
@@ -49,7 +49,6 @@ class ReferenceManager:
|
|
|
49
49
|
|
|
50
50
|
def get_tool_chunks(self) -> dict[str, tool_chunks]:
|
|
51
51
|
return self._tool_chunks
|
|
52
|
-
|
|
53
52
|
|
|
54
53
|
def get_chunks_of_all_tools(self) -> list[list[ContentChunk]]:
|
|
55
54
|
return [tool_chunks.chunks for tool_chunks in self._tool_chunks.values()]
|
|
@@ -57,12 +56,12 @@ class ReferenceManager:
|
|
|
57
56
|
def get_chunks_of_tool(self, tool_call_id: str) -> list[ContentChunk]:
|
|
58
57
|
return self._tool_chunks.get(tool_call_id, tool_chunks("", [])).chunks
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
def replace_chunks_of_tool(
|
|
60
|
+
self, tool_call_id: str, chunks: list[ContentChunk]
|
|
61
|
+
) -> None:
|
|
62
62
|
if tool_call_id in self._tool_chunks:
|
|
63
63
|
self._tool_chunks[tool_call_id].chunks = chunks
|
|
64
64
|
|
|
65
|
-
|
|
66
65
|
def replace(self, chunks: list[ContentChunk]):
|
|
67
66
|
self._chunks = chunks
|
|
68
67
|
|
|
@@ -4,11 +4,11 @@ from logging import getLogger
|
|
|
4
4
|
from typing import Generic, Type, TypeVar
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel
|
|
7
|
+
|
|
7
8
|
from unique_toolkit.short_term_memory.schemas import ShortTermMemory
|
|
8
9
|
from unique_toolkit.short_term_memory.service import ShortTermMemoryService
|
|
9
10
|
from unique_toolkit.tools.utils.execution.execution import SafeTaskExecutor
|
|
10
11
|
|
|
11
|
-
|
|
12
12
|
TSchema = TypeVar("TSchema", bound=BaseModel)
|
|
13
13
|
|
|
14
14
|
|
|
@@ -50,6 +50,7 @@ class PersistentShortMemoryManager(Generic[TSchema]):
|
|
|
50
50
|
|
|
51
51
|
The PersistentShortMemoryManager is designed to handle short-term memory efficiently, ensuring data integrity and optimized storage.
|
|
52
52
|
"""
|
|
53
|
+
|
|
53
54
|
def __init__(
|
|
54
55
|
self,
|
|
55
56
|
short_term_memory_service: ShortTermMemoryService,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from logging import Logger
|
|
2
|
+
|
|
2
3
|
from pydantic import BaseModel, Field
|
|
3
4
|
|
|
4
5
|
from unique_toolkit.chat.service import ChatService
|
|
5
6
|
from unique_toolkit.language_model.schemas import (
|
|
6
|
-
LanguageModelAssistantMessage,
|
|
7
7
|
LanguageModelStreamResponse,
|
|
8
8
|
)
|
|
9
9
|
from unique_toolkit.tools.tool_progress_reporter import (
|
|
@@ -36,6 +36,7 @@ class ThinkingManager:
|
|
|
36
36
|
|
|
37
37
|
The ThinkingManager enhances transparency and user understanding by providing a clear view of the assistant's reasoning process.
|
|
38
38
|
"""
|
|
39
|
+
|
|
39
40
|
def __init__(
|
|
40
41
|
self,
|
|
41
42
|
logger: Logger,
|
unique_toolkit/tools/config.py
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
from enum import StrEnum
|
|
2
|
+
from typing import TYPE_CHECKING, Any
|
|
3
|
+
|
|
2
4
|
import humps
|
|
3
|
-
from typing import Any
|
|
4
|
-
from pydantic.fields import ComputedFieldInfo, FieldInfo
|
|
5
|
-
from pydantic.alias_generators import to_camel
|
|
6
5
|
from pydantic import (
|
|
7
6
|
BaseModel,
|
|
8
7
|
ConfigDict,
|
|
@@ -10,8 +9,8 @@ from pydantic import (
|
|
|
10
9
|
ValidationInfo,
|
|
11
10
|
model_validator,
|
|
12
11
|
)
|
|
13
|
-
|
|
14
|
-
from
|
|
12
|
+
from pydantic.alias_generators import to_camel
|
|
13
|
+
from pydantic.fields import ComputedFieldInfo, FieldInfo
|
|
15
14
|
|
|
16
15
|
if TYPE_CHECKING:
|
|
17
16
|
from unique_toolkit.tools.schemas import BaseToolConfig
|
unique_toolkit/tools/factory.py
CHANGED
|
@@ -1,18 +1,12 @@
|
|
|
1
|
-
from typing import Callable
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
from unique_toolkit.tools.tool import Tool
|
|
1
|
+
from typing import TYPE_CHECKING, Callable
|
|
5
2
|
|
|
6
3
|
from unique_toolkit.tools.schemas import BaseToolConfig
|
|
4
|
+
from unique_toolkit.tools.tool import Tool
|
|
7
5
|
|
|
8
|
-
|
|
9
|
-
from typing import TYPE_CHECKING
|
|
10
6
|
if TYPE_CHECKING:
|
|
11
7
|
from unique_toolkit.tools.config import ToolBuildConfig
|
|
12
8
|
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
|
|
16
10
|
class ToolFactory:
|
|
17
11
|
tool_map: dict[str, type[Tool]] = {}
|
|
18
12
|
tool_config_map: dict[str, Callable] = {}
|
unique_toolkit/tools/schemas.py
CHANGED
|
@@ -4,8 +4,8 @@ import re
|
|
|
4
4
|
from typing import Any, Optional
|
|
5
5
|
|
|
6
6
|
from pydantic import BaseModel, ConfigDict, Field, field_serializer, field_validator
|
|
7
|
-
from unique_toolkit.content.schemas import ContentChunk
|
|
8
7
|
|
|
8
|
+
from unique_toolkit.content.schemas import ContentChunk
|
|
9
9
|
from unique_toolkit.tools.config import get_configuration_dict
|
|
10
10
|
from unique_toolkit.tools.utils.source_handling.schema import SourceFormatConfig
|
|
11
11
|
|
unique_toolkit/tools/tool.py
CHANGED
|
@@ -1,24 +1,20 @@
|
|
|
1
1
|
from abc import ABC, abstractmethod
|
|
2
|
-
from enum import StrEnum
|
|
3
2
|
from logging import getLogger
|
|
4
|
-
from typing import Generic, TypeVar
|
|
5
|
-
from typing import Any, cast
|
|
3
|
+
from typing import Any, Generic, TypeVar, cast
|
|
6
4
|
|
|
7
|
-
from pydantic import Field
|
|
8
5
|
from typing_extensions import deprecated
|
|
6
|
+
|
|
9
7
|
from unique_toolkit.app.schemas import ChatEvent
|
|
10
8
|
from unique_toolkit.chat.service import (
|
|
11
9
|
ChatService,
|
|
12
10
|
)
|
|
11
|
+
from unique_toolkit.evals.schemas import EvaluationMetricName
|
|
13
12
|
from unique_toolkit.language_model import LanguageModelToolDescription
|
|
14
13
|
from unique_toolkit.language_model.schemas import (
|
|
15
14
|
LanguageModelFunction,
|
|
16
15
|
LanguageModelMessage,
|
|
17
16
|
)
|
|
18
17
|
from unique_toolkit.language_model.service import LanguageModelService
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
from unique_toolkit.evals.schemas import EvaluationMetricName
|
|
22
18
|
from unique_toolkit.tools.config import ToolBuildConfig, ToolSelectionPolicy
|
|
23
19
|
from unique_toolkit.tools.schemas import BaseToolConfig, ToolCallResponse, ToolPrompts
|
|
24
20
|
from unique_toolkit.tools.tool_progress_reporter import ToolProgressReporter
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
from logging import Logger, getLogger
|
|
3
|
+
|
|
3
4
|
from pydantic import BaseModel, Field
|
|
5
|
+
|
|
4
6
|
from unique_toolkit.app.schemas import ChatEvent
|
|
7
|
+
from unique_toolkit.evals.schemas import EvaluationMetricName
|
|
5
8
|
from unique_toolkit.language_model.schemas import (
|
|
6
9
|
LanguageModelFunction,
|
|
7
10
|
LanguageModelTool,
|
|
@@ -13,7 +16,6 @@ from unique_toolkit.tools.schemas import ToolCallResponse, ToolPrompts
|
|
|
13
16
|
from unique_toolkit.tools.tool import Tool
|
|
14
17
|
from unique_toolkit.tools.tool_progress_reporter import ToolProgressReporter
|
|
15
18
|
from unique_toolkit.tools.utils.execution.execution import Result, SafeTaskExecutor
|
|
16
|
-
from unique_toolkit.evals.schemas import EvaluationMetricName
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
class ForcedToolOption:
|
|
@@ -36,7 +38,6 @@ class ToolManagerConfig(BaseModel):
|
|
|
36
38
|
)
|
|
37
39
|
|
|
38
40
|
|
|
39
|
-
|
|
40
41
|
class ToolManager:
|
|
41
42
|
"""
|
|
42
43
|
Manages the tools available to the agent and executes tool calls.
|