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.
Files changed (39) hide show
  1. unique_toolkit/_common/default_language_model.py +1 -1
  2. unique_toolkit/_common/token/token_counting.py +9 -20
  3. unique_toolkit/_common/validators.py +2 -3
  4. unique_toolkit/debug_info_manager/debug_info_manager.py +0 -1
  5. unique_toolkit/evals/config.py +0 -1
  6. unique_toolkit/evals/context_relevancy/schema.py +1 -6
  7. unique_toolkit/evals/context_relevancy/service.py +13 -13
  8. unique_toolkit/evals/evaluation_manager.py +10 -12
  9. unique_toolkit/evals/hallucination/constants.py +0 -1
  10. unique_toolkit/evals/hallucination/hallucination_evaluation.py +5 -8
  11. unique_toolkit/evals/hallucination/service.py +0 -1
  12. unique_toolkit/evals/hallucination/utils.py +7 -8
  13. unique_toolkit/evals/output_parser.py +1 -1
  14. unique_toolkit/evals/schemas.py +2 -1
  15. unique_toolkit/evals/tests/test_context_relevancy_service.py +10 -9
  16. unique_toolkit/evals/tests/test_output_parser.py +8 -4
  17. unique_toolkit/history_manager/history_construction_with_contents.py +10 -20
  18. unique_toolkit/history_manager/history_manager.py +11 -22
  19. unique_toolkit/history_manager/loop_token_reducer.py +121 -109
  20. unique_toolkit/history_manager/utils.py +0 -1
  21. unique_toolkit/language_model/infos.py +1 -1
  22. unique_toolkit/language_model/schemas.py +0 -1
  23. unique_toolkit/postprocessor/postprocessor_manager.py +1 -3
  24. unique_toolkit/reference_manager/reference_manager.py +3 -4
  25. unique_toolkit/short_term_memory/persistent_short_term_memory_manager.py +2 -1
  26. unique_toolkit/thinking_manager/thinking_manager.py +2 -1
  27. unique_toolkit/tools/config.py +4 -5
  28. unique_toolkit/tools/factory.py +2 -8
  29. unique_toolkit/tools/schemas.py +1 -1
  30. unique_toolkit/tools/test/test_tool_progress_reporter.py +1 -0
  31. unique_toolkit/tools/tool.py +3 -7
  32. unique_toolkit/tools/tool_manager.py +3 -2
  33. unique_toolkit/tools/tool_progress_reporter.py +1 -0
  34. unique_toolkit/tools/utils/source_handling/schema.py +0 -1
  35. unique_toolkit/tools/utils/source_handling/tests/test_source_formatting.py +1 -0
  36. {unique_toolkit-0.8.18.dist-info → unique_toolkit-0.8.19.dist-info}/METADATA +5 -1
  37. {unique_toolkit-0.8.18.dist-info → unique_toolkit-0.8.19.dist-info}/RECORD +39 -39
  38. {unique_toolkit-0.8.18.dist-info → unique_toolkit-0.8.19.dist-info}/LICENSE +0 -0
  39. {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 unique_toolkit._common.token.token_counting import num_token_for_language_model_messages
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 FileContentSerialization, get_full_history_with_contents
15
- from unique_toolkit.language_model.schemas import LanguageModelAssistantMessage, LanguageModelMessage, LanguageModelMessageRole, LanguageModelMessages, LanguageModelSystemMessage, LanguageModelToolMessage, LanguageModelUserMessage
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( self,
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
- ) -> LanguageModelMessages:
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
- original_user_message,
83
- rendered_user_message_string,
84
- rendered_system_message_string,
85
- loop_history,
86
- remove_from_text
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(history_from_db, original_user_message, rendered_user_message_string)
137
- system_message = LanguageModelSystemMessage(content=rendered_system_message_string)
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(self,loop_history: list[LanguageModelMessage]) -> list[LanguageModelMessage]:
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(loop_history)
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"] = rendered_user_message_string + added_to_message_by_history
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(original_user_message, "")
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
- user_message=self._user_message,
203
- chat_id=self._chat_id,
204
- chat_service=self._chat_service,
205
- content_service=self._content_service,
206
- file_content_serialization_type=(
207
- FileContentSerialization.NONE
208
- if self._has_uploaded_content_config
209
- else FileContentSerialization.FILE_NAME
210
- ),
211
- )
212
-
213
- full_history.root = await self._clean_messages(full_history.root, remove_from_text)
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[LanguageModelMessage | LanguageModelToolMessage | LanguageModelAssistantMessage | LanguageModelSystemMessage | LanguageModelUserMessage],
246
- remove_from_text: Callable[[str], Awaitable[str]]
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
- self,
278
- history: list[LanguageModelMessage],
298
+ self,
299
+ history: list[LanguageModelMessage],
279
300
  ) -> list[LanguageModelMessage]:
280
- """
281
- Reduce the message length by removing the last source result of each tool call.
282
- If there is only one source for a tool call, the tool call message is returned unchanged.
283
- """
284
- history_reduced: list[LanguageModelMessage] = []
285
- content_chunks_reduced: list[ContentChunk] = []
286
- chunk_offset = 0
287
- source_offset = 0
288
-
289
- for message in history:
290
- if self._should_reduce_message(message):
291
- result = self._reduce_sources_in_tool_message(
292
- message, # type: ignore
293
- chunk_offset,
294
- source_offset,
295
- )
296
- content_chunks_reduced.extend(result.reduced_chunks)
297
- history_reduced.append(result.message)
298
- chunk_offset = result.chunk_offset
299
- source_offset = result.source_offset
300
- else:
301
- history_reduced.append(message)
302
-
303
- self._reference_manager.replace(chunks=content_chunks_reduced)
304
- return history_reduced
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
- """Determine if a message should have its sources reduced."""
308
- return (
309
- message.role == LanguageModelMessageRole.TOOL
310
- and isinstance(message, LanguageModelToolMessage)
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,
@@ -13,7 +13,6 @@ from unique_toolkit.tools.utils.source_handling.schema import (
13
13
  SourceFormatConfig,
14
14
  )
15
15
 
16
-
17
16
  logger = logging.getLogger(__name__)
18
17
 
19
18
 
@@ -875,7 +875,7 @@ class LanguageModelInfo(BaseModel):
875
875
  deprecated_at=date(2026, 8, 7),
876
876
  retirement_at=date(2026, 8, 7),
877
877
  )
878
-
878
+
879
879
  case _:
880
880
  if isinstance(model_name, LanguageModelName):
881
881
  raise ValueError(
@@ -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
- def replace_chunks_of_tool(self, tool_call_id: str,chunks: list[ContentChunk]) -> None:
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,
@@ -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 typing import TYPE_CHECKING
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
@@ -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] = {}
@@ -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
 
@@ -1,6 +1,7 @@
1
1
  from unittest.mock import AsyncMock
2
2
 
3
3
  import pytest
4
+
4
5
  from unique_toolkit.chat.service import ChatService
5
6
  from unique_toolkit.content.schemas import ContentReference
6
7
  from unique_toolkit.language_model.schemas import LanguageModelFunction
@@ -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.
@@ -5,6 +5,7 @@ from functools import wraps
5
5
  from typing import Protocol
6
6
 
7
7
  from pydantic import BaseModel
8
+
8
9
  from unique_toolkit.chat.service import ChatService
9
10
  from unique_toolkit.content.schemas import ContentReference
10
11
  from unique_toolkit.language_model.schemas import (
@@ -3,7 +3,6 @@ from pydantic import BaseModel
3
3
 
4
4
  from unique_toolkit.tools.config import get_configuration_dict
5
5
 
6
-
7
6
  SOURCE_TEMPLATE = "<source${index}>${document}${info}${text}</source${index}>"
8
7
  SECTIONS = {
9
8
  "document": "<|document|>{}<|/document|>\n",
@@ -1,4 +1,5 @@
1
1
  import pytest
2
+
2
3
  from unique_toolkit.content.schemas import ContentChunk
3
4
  from unique_toolkit.tools.utils.source_handling.schema import SourceFormatConfig
4
5
  from unique_toolkit.tools.utils.source_handling.source_formatting import (