unique_toolkit 0.8.12__py3-none-any.whl → 0.8.14__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.
@@ -0,0 +1,102 @@
1
+ from logging import Logger
2
+ from pydantic import BaseModel, Field
3
+
4
+ from unique_toolkit.chat.service import ChatService
5
+ from unique_toolkit.language_model.schemas import (
6
+ LanguageModelAssistantMessage,
7
+ LanguageModelStreamResponse,
8
+ )
9
+ from unique_toolkit.tools.tool_progress_reporter import (
10
+ ToolProgressReporter,
11
+ )
12
+
13
+
14
+ class ThinkingManagerConfig(BaseModel):
15
+ thinking_steps_display: bool = Field(
16
+ default=True, description="Whether to display thinking steps in the chat."
17
+ )
18
+
19
+
20
+ class ThinkingManager:
21
+ """
22
+ Manages the display and tracking of thinking steps during response generation.
23
+
24
+ This class is responsible for:
25
+ - Tracking and formatting thinking steps as part of the response process.
26
+ - Updating the tool progress reporter with the latest thinking step information.
27
+ - Managing the display of thinking steps in the assistant's response.
28
+ - Closing and finalizing the thinking steps section when the process is complete.
29
+
30
+ Key Features:
31
+ - Thinking Step Tracking: Maintains a sequential log of thinking steps with step numbers.
32
+ - Configurable Display: Supports enabling or disabling the display of thinking steps based on configuration.
33
+ - Integration with Tool Progress: Updates the tool progress reporter to reflect the current thinking state.
34
+ - Dynamic Response Updates: Modifies the assistant's response to include or finalize thinking steps.
35
+ - Flexible Formatting: Formats thinking steps in a structured and user-friendly HTML-like format.
36
+
37
+ The ThinkingManager enhances transparency and user understanding by providing a clear view of the assistant's reasoning process.
38
+ """
39
+ def __init__(
40
+ self,
41
+ logger: Logger,
42
+ config: ThinkingManagerConfig,
43
+ tool_progress_reporter: ToolProgressReporter,
44
+ chat_service: ChatService,
45
+ ):
46
+ self._chat_service = chat_service
47
+ self._config = config
48
+ self._thinking_steps = ""
49
+ self._thinking_step_number = 1
50
+ self._tool_progress_reporter = tool_progress_reporter
51
+
52
+ def thinking_is_displayed(self) -> bool:
53
+ return self._config.thinking_steps_display
54
+
55
+ def update_tool_progress_reporter(self, loop_response: LanguageModelStreamResponse):
56
+ if self._config.thinking_steps_display and (
57
+ not loop_response.message.text
58
+ == self._tool_progress_reporter._progress_start_text
59
+ ):
60
+ self._tool_progress_reporter.tool_statuses = {}
61
+ self._tool_progress_reporter._progress_start_text = (
62
+ loop_response.message.text
63
+ )
64
+
65
+ def update_start_text(
66
+ self, start_text: str, loop_response: LanguageModelStreamResponse
67
+ ) -> str:
68
+ if not self._config.thinking_steps_display:
69
+ return start_text
70
+ if not loop_response.message.original_text:
71
+ return start_text
72
+ if loop_response.message.original_text == "":
73
+ return start_text
74
+
75
+ update_message = loop_response.message.original_text
76
+
77
+ if start_text == "":
78
+ self._thinking_steps = f"\n<i><b>Step 1:</b>\n{update_message}</i>\n"
79
+ start_text = f"""<details open>\n<summary><b>Thinking steps</b></summary>\n{self._thinking_steps}\n</details>\n\n---\n\n"""
80
+ else:
81
+ self._thinking_steps += f"\n\n<i><b>Step {self._thinking_step_number}:</b>\n{update_message}</i>\n\n"
82
+ start_text = f"""<details open>\n<summary><b>Thinking steps</b></summary>\n<i>{self._thinking_steps}\n\n</i>\n</details>\n\n---\n\n"""
83
+
84
+ self._thinking_step_number += 1
85
+ return start_text
86
+
87
+ def close_thinking_steps(self, loop_response: LanguageModelStreamResponse):
88
+ if not self._config.thinking_steps_display:
89
+ return
90
+ if not self._thinking_steps:
91
+ return
92
+ if not loop_response.message.text:
93
+ return
94
+ if not loop_response.message.text.startswith("<details open>"):
95
+ return
96
+
97
+ loop_response.message.text = loop_response.message.text.replace(
98
+ "<details open>", "<details>"
99
+ )
100
+
101
+ self._chat_service.modify_assistant_message(content=loop_response.message.text)
102
+ return
@@ -134,5 +134,4 @@ class ToolPrompts(BaseModel):
134
134
  display_name: str
135
135
  tool_description: str
136
136
  tool_format_information_for_system_prompt: str
137
- tool_format_information_for_system_prompt: str
138
137
  input_model: dict[str, Any]
@@ -18,7 +18,7 @@ from unique_toolkit.language_model.schemas import (
18
18
  from unique_toolkit.language_model.service import LanguageModelService
19
19
 
20
20
 
21
- from unique_toolkit.evaluators.schemas import EvaluationMetricName
21
+ from unique_toolkit.evals.schemas import EvaluationMetricName
22
22
  from unique_toolkit.tools.agent_chunks_handler import AgentChunksHandler
23
23
  from unique_toolkit.tools.config import ToolBuildConfig, ToolSelectionPolicy
24
24
  from unique_toolkit.tools.schemas import BaseToolConfig, ToolCallResponse, ToolPrompts
@@ -4,6 +4,7 @@ from pydantic import BaseModel, Field
4
4
  from unique_toolkit.app.schemas import ChatEvent
5
5
  from unique_toolkit.language_model.schemas import (
6
6
  LanguageModelFunction,
7
+ LanguageModelTool,
7
8
  LanguageModelToolDescription,
8
9
  )
9
10
  from unique_toolkit.tools.config import ToolBuildConfig
@@ -12,6 +13,7 @@ from unique_toolkit.tools.schemas import ToolCallResponse, ToolPrompts
12
13
  from unique_toolkit.tools.tool import Tool
13
14
  from unique_toolkit.tools.tool_progress_reporter import ToolProgressReporter
14
15
  from unique_toolkit.tools.utils.execution.execution import Result, SafeTaskExecutor
16
+ from unique_toolkit.evals.schemas import EvaluationMetricName
15
17
 
16
18
 
17
19
  class ForcedToolOption:
@@ -67,16 +69,18 @@ class ToolManager:
67
69
  tool_progress_reporter: ToolProgressReporter,
68
70
  ):
69
71
  self._logger = logger
70
- self._config = config
72
+ self._config = config
71
73
  self._tool_progress_reporter = tool_progress_reporter
72
74
  self._tools = []
73
75
  self._tool_choices = event.payload.tool_choices
74
76
  self._disabled_tools = event.payload.disabled_tools
77
+ # this needs to be a set of strings to avoid duplicates
78
+ self._tool_evaluation_check_list: set[EvaluationMetricName] = set()
75
79
  self._init__tools(event)
76
80
 
77
- def _init__tools(self, event: ChatEvent) -> None:
81
+ def _init__tools(self, event: ChatEvent) -> None:
78
82
  tool_choices = self._tool_choices
79
- tool_configs = self._config .tools
83
+ tool_configs = self._config.tools
80
84
  self._logger.info("Initializing tool definitions...")
81
85
  self._logger.info(f"Tool choices: {tool_choices}")
82
86
  self._logger.info(f"Tool configs: {tool_configs}")
@@ -105,6 +109,9 @@ class ToolManager:
105
109
 
106
110
  self._tools.append(t)
107
111
 
112
+ def get_evaluation_check_list(self) -> list[EvaluationMetricName]:
113
+ return list(self._tool_evaluation_check_list)
114
+
108
115
  def log_loaded_tools(self):
109
116
  self._logger.info(f"Loaded tools: {[tool.name for tool in self._tools]}")
110
117
 
@@ -118,9 +125,15 @@ class ToolManager:
118
125
  return None
119
126
 
120
127
  def get_forced_tools(self) -> list[ForcedToolOption]:
121
- return [ForcedToolOption(t.name) for t in self._tools if t.name in self._tool_choices]
128
+ return [
129
+ ForcedToolOption(t.name)
130
+ for t in self._tools
131
+ if t.name in self._tool_choices
132
+ ]
122
133
 
123
- def get_tool_definitions(self) -> list[LanguageModelToolDescription]:
134
+ def get_tool_definitions(
135
+ self,
136
+ ) -> list[LanguageModelTool | LanguageModelToolDescription]:
124
137
  return [tool.tool_description() for tool in self._tools]
125
138
 
126
139
  def get_tool_prompts(self) -> list[ToolPrompts]:
@@ -137,19 +150,19 @@ class ToolManager:
137
150
  )
138
151
  num_tool_calls = len(tool_calls)
139
152
 
140
- if num_tool_calls > self._config .max_tool_calls:
153
+ if num_tool_calls > self._config.max_tool_calls:
141
154
  self._logger.warning(
142
155
  (
143
156
  "Number of tool calls %s exceeds the allowed maximum of %s."
144
157
  "The tool calls will be reduced to the first %s."
145
158
  ),
146
159
  num_tool_calls,
147
- self._config .max_tool_calls,
148
- self._config .max_tool_calls,
160
+ self._config.max_tool_calls,
161
+ self._config.max_tool_calls,
149
162
  )
150
- tool_calls = tool_calls[: self._config .max_tool_calls]
163
+ tool_calls = tool_calls[: self._config.max_tool_calls]
151
164
 
152
- tool_call_responses = await self._execute_parallelized(tool_calls=tool_calls)
165
+ tool_call_responses = await self._execute_parallelized(tool_calls)
153
166
  return tool_call_responses
154
167
 
155
168
  async def _execute_parallelized(
@@ -194,6 +207,9 @@ class ToolManager:
194
207
  tool_response: ToolCallResponse = await tool_instance.run(
195
208
  tool_call=tool_call
196
209
  )
210
+ evaluation_checks = tool_instance.evaluation_check_list()
211
+ self._tool_evaluation_check_list.update(evaluation_checks)
212
+
197
213
  return tool_response
198
214
 
199
215
  return ToolCallResponse(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 0.8.12
3
+ Version: 0.8.14
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Martin Fadler
@@ -114,6 +114,17 @@ All notable changes to this project will be documented in this file.
114
114
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
115
115
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
116
116
 
117
+ ## [0.8.14] - 2025-08-19
118
+ - Including GPT-5 series deployed via LiteLLM into language model info
119
+
120
+ ## [0.8.13] - 2025-08-18
121
+ - Adding initial versions of
122
+ - Evaluation Manager
123
+ - History Manager
124
+ - Postprocessor Manager
125
+ - Thinking Manager
126
+ - Updated tool manager
127
+
117
128
  ## [0.8.12] - 2025-08-18
118
129
  - Fix no tool call respoonse in ChatMessage -> Open Ai messages translation
119
130
  - Add simple append method to OpenAIMessageBuilder
@@ -3,7 +3,7 @@ unique_toolkit/_common/_base_service.py,sha256=S8H0rAebx7GsOldA7xInLp3aQJt9yEPDQ
3
3
  unique_toolkit/_common/_time_utils.py,sha256=ztmTovTvr-3w71Ns2VwXC65OKUUh-sQlzbHdKTQWm-w,135
4
4
  unique_toolkit/_common/exception.py,sha256=caQIE1btsQnpKCHqL2cgWUSbHup06enQu_Pt7uGUTTE,727
5
5
  unique_toolkit/_common/validate_required_values.py,sha256=Y_M1ub9gIKP9qZ45F6Zq3ZHtuIqhmOjl8Z2Vd3avg8w,588
6
- unique_toolkit/_common/validators.py,sha256=l7-hWyRTZ3aF_e73oTQFZdz93s06VhNWVpkERbg2a64,1569
6
+ unique_toolkit/_common/validators.py,sha256=uPGPkeygNi3KimWZxKOKYFxwpCxTkhhYBAn-b_5TS_M,2584
7
7
  unique_toolkit/app/__init__.py,sha256=ETxYDpEizg_PKmi4JPX_P76ySq-us-xypfAIdKQ1QZU,1284
8
8
  unique_toolkit/app/dev_util.py,sha256=rN-xSg4OGfmwjaToy8m_hQroehcLYyk9-GCmQJ-f6uY,4302
9
9
  unique_toolkit/app/init_logging.py,sha256=Sh26SRxOj8i8dzobKhYha2lLrkrMTHfB1V4jR3h23gQ,678
@@ -32,6 +32,9 @@ unique_toolkit/embedding/functions.py,sha256=3qp-BfuMAbnp8YB04rh3xH8vsJuCBPizoy-
32
32
  unique_toolkit/embedding/schemas.py,sha256=1GvKCaSk4jixzVQ2PKq8yDqwGEVY_hWclYtoAr6CC2g,96
33
33
  unique_toolkit/embedding/service.py,sha256=2KjYlUKxeh-Je8S1mOPiQ735pqAmdbeztycVNJxcUXA,5039
34
34
  unique_toolkit/embedding/utils.py,sha256=v86lo__bCJbxZBQ3OcLu5SuwT6NbFfWlcq8iyk6BuzQ,279
35
+ unique_toolkit/evals/evaluation_manager.py,sha256=_4XF2JY8EZd8kRmaZzF1S5R0kNATKTzgpE0ZIQDqQLE,7711
36
+ unique_toolkit/evals/exception.py,sha256=7lcVbCyoN4Md1chNJDFxpUYyWbVrcr9dcc3TxWykJTc,115
37
+ unique_toolkit/evals/schemas.py,sha256=VwxT_L_1Fima1RwGWajp1DIPy36-4n23_eCFkK3MjTM,3114
35
38
  unique_toolkit/evaluators/__init__.py,sha256=3Rfpnowm7MUXHWmeU4UV4s_3Hk-sw3V20oBwQCYlejQ,50
36
39
  unique_toolkit/evaluators/config.py,sha256=_DIXToJ-hGNpDAdWa7Q6GMjAsxiC_DquLF-SS5s9rTE,717
37
40
  unique_toolkit/evaluators/constants.py,sha256=1oI93jsh0R_TjX_8OenliiiywVe3vTooSnaMqtq6R18,27
@@ -51,38 +54,43 @@ unique_toolkit/framework_utilities/langchain/history.py,sha256=R9RuCeSFNaUO3OZ0G
51
54
  unique_toolkit/framework_utilities/openai/client.py,sha256=IasxPXlVJHIsZdXHin7yq-5tO4RNLUu9cEuhrgb4ghE,1205
52
55
  unique_toolkit/framework_utilities/openai/message_builder.py,sha256=VU6mJm_upLcarJQKFft_t1RlLRncWDxDuLC5LIJ5lQQ,4339
53
56
  unique_toolkit/framework_utilities/utils.py,sha256=JK7g2yMfEx3eMprug26769xqNpS5WJcizf8n2zWMBng,789
57
+ unique_toolkit/history_manager/history_manager.py,sha256=ScC9CrkJCNbxFbWqTO-vpPlCUAUADpJCX2AqUd4Ff04,10104
58
+ unique_toolkit/history_manager/utils.py,sha256=3GT53SfOQ7g-dN3PHFIPaAab74sUfV28hbUtGMdX-bY,5607
54
59
  unique_toolkit/language_model/__init__.py,sha256=lRQyLlbwHbNFf4-0foBU13UGb09lwEeodbVsfsSgaCk,1971
55
60
  unique_toolkit/language_model/builder.py,sha256=4OKfwJfj3TrgO1ezc_ewIue6W7BCQ2ZYQXUckWVPPTA,3369
56
61
  unique_toolkit/language_model/constants.py,sha256=B-topqW0r83dkC_25DeQfnPk3n53qzIHUCBS7YJ0-1U,119
57
62
  unique_toolkit/language_model/functions.py,sha256=-nWgcscaZvEfuf2ftCQj8hyFY2RynPFO8XgX2gsN924,16665
58
- unique_toolkit/language_model/infos.py,sha256=7huMpiDhGdWyhFBZx9dVLXdSkONSrxHL1Fr7zTBeX0w,40062
63
+ unique_toolkit/language_model/infos.py,sha256=MbuXYtyTLik-7KTKlyQCjW3uNRTT5ddTvbpSarFxzPk,45715
59
64
  unique_toolkit/language_model/prompt.py,sha256=JSawaLjQg3VR-E2fK8engFyJnNdk21zaO8pPIodzN4Q,3991
60
65
  unique_toolkit/language_model/reference.py,sha256=nkX2VFz-IrUz8yqyc3G5jUMNwrNpxITBrMEKkbqqYoI,8583
61
66
  unique_toolkit/language_model/schemas.py,sha256=p95cAwrYmEBupI8f7JZY17aJTKEHvtqF88hMIzS5r_k,16259
62
67
  unique_toolkit/language_model/service.py,sha256=N_I3VtK5B0G8s5c6TcBVWM7CcLGqakDhEdHQ_z-Hcok,11676
63
68
  unique_toolkit/language_model/utils.py,sha256=bPQ4l6_YO71w-zaIPanUUmtbXC1_hCvLK0tAFc3VCRc,1902
69
+ unique_toolkit/postprocessor/postprocessor_manager.py,sha256=68TAcXMU_ohWOtzo91LntY950HV9I9gGU92-V0Mxmr8,4239
64
70
  unique_toolkit/protocols/support.py,sha256=V15WEIFKVMyF1QCnR8vIi4GrJy4dfTCB6d6JlqPZ58o,2341
65
- unique_toolkit/reference_manager/reference_manager.py,sha256=FNCW4CQSsimS8UG7OTdu4-JNQXUMhPrOfRuKAbK9vvE,2305
71
+ unique_toolkit/reference_manager/reference_manager.py,sha256=JofRoTcnB-Azj9X10kmhqqTUUyPp4GRRWBmaiybzaUo,3446
66
72
  unique_toolkit/short_term_memory/__init__.py,sha256=2mI3AUrffgH7Yt-xS57EGqnHf7jnn6xquoKEhJqk3Wg,185
67
73
  unique_toolkit/short_term_memory/constants.py,sha256=698CL6-wjup2MvU19RxSmQk3gX7aqW_OOpZB7sbz_Xg,34
68
74
  unique_toolkit/short_term_memory/functions.py,sha256=3WiK-xatY5nh4Dr5zlDUye1k3E6kr41RiscwtTplw5k,4484
75
+ unique_toolkit/short_term_memory/persistent_short_term_memory_manager.py,sha256=AUzUKpIYFPeL6Wa42PWO031FrhKMOxAj-OwrJHFspbY,5830
69
76
  unique_toolkit/short_term_memory/schemas.py,sha256=OhfcXyF6ACdwIXW45sKzjtZX_gkcJs8FEZXcgQTNenw,1406
70
77
  unique_toolkit/short_term_memory/service.py,sha256=5PeVBu1ZCAfyDb2HLVvlmqSbyzBBuE9sI2o9Aajqjxg,8884
71
78
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
79
  unique_toolkit/smart_rules/compile.py,sha256=cxWjb2dxEI2HGsakKdVCkSNi7VK9mr08w5sDcFCQyWI,9553
80
+ unique_toolkit/thinking_manager/thinking_manager.py,sha256=_7G4RJM4Or66myx2AJ2UNk1vhQXV7_uLXlIxmumgmKk,4208
73
81
  unique_toolkit/tools/agent_chunks_handler.py,sha256=ORjC22ulfHTfPxUHmU7QU0H53j3AdLmt1a0opeI91V8,1809
74
82
  unique_toolkit/tools/config.py,sha256=9bYxdDuUPmAxhYyIdLbmXLzX1X2AUw--_WISQxQ4G2U,3003
75
83
  unique_toolkit/tools/factory.py,sha256=vxxchbPTrk2lVjSMdpcFN-6FRcMLiy-NgHHS3w0wYCA,1271
76
- unique_toolkit/tools/schemas.py,sha256=C9caE0EZNS6iGBPz2fsW5_Bao4GGGbAOda5D-XjnAQ0,4743
84
+ unique_toolkit/tools/schemas.py,sha256=IngcnYCqaAVl3ADbW-j_-ZXlPK1oVKeXqHDyXJH8Bso,4692
77
85
  unique_toolkit/tools/test/test_tool_progress_reporter.py,sha256=YCR7uJ4_sn-z3CJskzSNWNDYYcThr9m2Q6gRBxbLVfg,6298
78
- unique_toolkit/tools/tool.py,sha256=Zx9E5YSkzZ_ZUhxLgSLP_iDI8aYGq5wgOahMrnhfNV0,5751
79
- unique_toolkit/tools/tool_manager.py,sha256=m1yt45rJ0OtC7wLVG5oqf_HvZygC7wV8g9OJWwr4ups,8490
86
+ unique_toolkit/tools/tool.py,sha256=UZ-WdScj_VBdBNMz56SwvdpIKGNZLKNy3lRsgJAr6EY,5746
87
+ unique_toolkit/tools/tool_manager.py,sha256=eXzx4608noza2At7yjqC2B44h4a7gv7lZMo1-xoLY98,9046
80
88
  unique_toolkit/tools/tool_progress_reporter.py,sha256=j6iVTpoLU_PjLwoK6fpIy9vmX_MLWF_-_v-nTDUcwas,7954
81
89
  unique_toolkit/tools/utils/execution/execution.py,sha256=vjG2Y6awsGNtlvyQAGCTthQ5thWHYnn-vzZXaYLb3QE,7922
82
90
  unique_toolkit/tools/utils/source_handling/schema.py,sha256=pvNhtL2daDLpCVIQpfdn6R35GvKmITVLXjZNLAwpgUE,871
83
91
  unique_toolkit/tools/utils/source_handling/source_formatting.py,sha256=C7uayNbdkNVJdEARA5CENnHtNY1SU6etlaqbgHNyxaQ,9152
84
92
  unique_toolkit/tools/utils/source_handling/tests/test_source_formatting.py,sha256=zu3AJnYH9CMqZPrxKEH3IgI-fM3nlvIBuspJG6W6B18,6978
85
- unique_toolkit-0.8.12.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
86
- unique_toolkit-0.8.12.dist-info/METADATA,sha256=EFm6wn8_fM4GsB6o9AypQeB49rtgJ9HX_c6lFk_sm8M,27377
87
- unique_toolkit-0.8.12.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
88
- unique_toolkit-0.8.12.dist-info/RECORD,,
93
+ unique_toolkit-0.8.14.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
94
+ unique_toolkit-0.8.14.dist-info/METADATA,sha256=5QadKjdIsrfsgxMGglGAN_qfn916APhtTcQWRc9S52c,27642
95
+ unique_toolkit-0.8.14.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
96
+ unique_toolkit-0.8.14.dist-info/RECORD,,