unique_toolkit 0.8.3__py3-none-any.whl → 0.8.5__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,215 @@
1
+ import pytest
2
+ from unique_toolkit.content.schemas import ContentChunk
3
+ from unique_toolkit.tools.utils.source_handling.schema import SourceFormatConfig
4
+ from unique_toolkit.tools.utils.source_handling.source_formatting import (
5
+ _format_page_range,
6
+ format_chunk,
7
+ )
8
+
9
+
10
+ @pytest.fixture
11
+ def default_config():
12
+ return SourceFormatConfig()
13
+
14
+
15
+ @pytest.fixture
16
+ def xml_style_config_without_page_number():
17
+ return SourceFormatConfig(
18
+ source_template="<source${index}>${document}${info}${text}</source${index}>",
19
+ sections={
20
+ "document": "<|document|>{}<|/document|>\n",
21
+ "info": "<|info|>{}<|/info|>\n",
22
+ },
23
+ )
24
+
25
+
26
+ @pytest.fixture
27
+ def xml_style_config_with_page_number():
28
+ return SourceFormatConfig(
29
+ source_template="<source${index}>${document}${page}${info}${text}</source${index}>",
30
+ sections={
31
+ "document": "<|document|>{}<|/document|>\n",
32
+ "info": "<|info|>{}<|/info|>\n",
33
+ "page": "<|page|>{}<|/page|>\n",
34
+ },
35
+ )
36
+
37
+
38
+ @pytest.fixture
39
+ def xml_style_config_with_metadata():
40
+ return SourceFormatConfig(
41
+ source_template="<source${index}>${document}${date}${text}</source${index}>",
42
+ sections={
43
+ "document": "<|document|>{}<|/document|>\n",
44
+ "date": "<|DateFromMetaData|>{}<|/DateFromMetaData|>\n",
45
+ },
46
+ )
47
+
48
+
49
+ @pytest.fixture
50
+ def json_style_config():
51
+ return SourceFormatConfig(
52
+ source_template="{'source_number': ${index}, 'content': '${document}${page}${info}${text}'}",
53
+ sections={
54
+ "document": "<|document|>{}<|/document|>\n",
55
+ "info": "<|info|>{}<|/info|>\n",
56
+ "page": "<|page|>{}<|/page|>\n",
57
+ },
58
+ )
59
+
60
+
61
+ def test_format_page_range():
62
+ # Test same start and end page
63
+ chunk = ContentChunk(id="1", order=1, text="test", start_page=1, end_page=1)
64
+ assert _format_page_range(chunk) == "1"
65
+
66
+ # Test page range
67
+ chunk = ContentChunk(id="1", order=1, text="test", start_page=1, end_page=3)
68
+ assert _format_page_range(chunk) == "1 - 3"
69
+
70
+ # Test invalid pages
71
+ chunk = ContentChunk(id="1", order=1, text="test", start_page=0, end_page=0)
72
+ assert _format_page_range(chunk) == ""
73
+
74
+
75
+ def test_json_style_formatting(json_style_config):
76
+ chunk = ContentChunk(
77
+ id="1",
78
+ order=1,
79
+ text="<|document|>Doc1<|/document|>\n<|info|>Important<|/info|>\nContent text",
80
+ start_page=1,
81
+ end_page=2,
82
+ )
83
+
84
+ formatted = format_chunk(1, chunk, json_style_config)
85
+ expected = "{'source_number': 1, 'content': '<|document|>Doc1<|/document|>\n<|page|>1 - 2<|/page|>\n<|info|>Important<|/info|>\nContent text'}"
86
+ assert formatted == expected
87
+
88
+
89
+ def test_metadata_handling(xml_style_config_with_metadata):
90
+ # Test with metadata that matches a section name
91
+ chunk = ContentChunk(
92
+ id="1",
93
+ order=1,
94
+ text="<|document|>Doc1<|/document|>\nContent text",
95
+ metadata={
96
+ "key": "metadata-key",
97
+ "mimeType": "text/plain",
98
+ "date": "12.03.2025",
99
+ }, # type: ignore
100
+ )
101
+
102
+ formatted = format_chunk(1, chunk, xml_style_config_with_metadata)
103
+ expected = "<source1><|document|>Doc1<|/document|>\n<|DateFromMetaData|>12.03.2025<|/DateFromMetaData|>\nContent text</source1>"
104
+ assert formatted == expected
105
+
106
+ # Test with metadata that doesn't match a section name
107
+ chunk = ContentChunk(
108
+ id="1",
109
+ order=1,
110
+ text="<|document|>Doc1<|/document|>\nContent text",
111
+ metadata={
112
+ "key": "metadata-key",
113
+ "mimeType": "text/plain",
114
+ "unrelated_key": "Some value",
115
+ }, # type: ignore
116
+ )
117
+
118
+ formatted = format_chunk(1, chunk, xml_style_config_with_metadata)
119
+ expected = "<source1><|document|>Doc1<|/document|>\nContent text</source1>"
120
+ assert formatted == expected
121
+
122
+ # Test with minimal metadata
123
+ chunk = ContentChunk(
124
+ id="1",
125
+ order=1,
126
+ text="<|document|>Doc1<|/document|>\nContent text",
127
+ metadata={"key": "metadata-key", "mimeType": "text/plain"}, # type: ignore
128
+ )
129
+
130
+ formatted = format_chunk(1, chunk, xml_style_config_with_metadata)
131
+ expected = "<source1><|document|>Doc1<|/document|>\nContent text</source1>"
132
+ assert formatted == expected
133
+
134
+
135
+ def test_default_style(
136
+ default_config,
137
+ ):
138
+ chunk = ContentChunk(
139
+ id="1",
140
+ order=1,
141
+ text="<|document|>Doc1<|/document|>\n<|info|>Important<|/info|>\nContent text",
142
+ start_page=1,
143
+ end_page=2,
144
+ )
145
+
146
+ formatted = format_chunk(1, chunk, default_config)
147
+ expected = "<source1><|document|>Doc1<|/document|>\n<|info|>Important<|/info|>\nContent text</source1>"
148
+ assert formatted == expected
149
+
150
+
151
+ def test_xml_style_without_page_number_formatting(
152
+ xml_style_config_without_page_number,
153
+ ):
154
+ chunk = ContentChunk(
155
+ id="1",
156
+ order=1,
157
+ text="<|document|>Doc1<|/document|>\n<|info|>Important<|/info|>\nContent text",
158
+ start_page=1,
159
+ end_page=2,
160
+ )
161
+
162
+ formatted = format_chunk(1, chunk, xml_style_config_without_page_number)
163
+ expected = "<source1><|document|>Doc1<|/document|>\n<|info|>Important<|/info|>\nContent text</source1>"
164
+ assert formatted == expected
165
+
166
+
167
+ def test_xml_style_with_page_number_formatting(
168
+ xml_style_config_with_page_number,
169
+ ):
170
+ chunk = ContentChunk(
171
+ id="1",
172
+ order=1,
173
+ text="<|document|>Doc1<|/document|>\n<|info|>Important<|/info|>\nContent text",
174
+ start_page=1,
175
+ end_page=2,
176
+ )
177
+
178
+ formatted = format_chunk(1, chunk, xml_style_config_with_page_number)
179
+ expected = "<source1><|document|>Doc1<|/document|>\n<|page|>1 - 2<|/page|>\n<|info|>Important<|/info|>\nContent text</source1>"
180
+ assert formatted == expected
181
+
182
+
183
+ def test_special_characters_handling(json_style_config):
184
+ chunk = ContentChunk(
185
+ id="1",
186
+ order=1,
187
+ text="<|document|>Doc's \"title\"<|/document|>\n<|info|>Info with {brackets}<|/info|>\nContent: with 'quotes'",
188
+ start_page=1,
189
+ end_page=1,
190
+ )
191
+
192
+ formatted = format_chunk(1, chunk, json_style_config)
193
+ expected = "{'source_number': 1, 'content': '<|document|>Doc's \"title\"<|/document|>\n<|page|>1<|/page|>\n<|info|>Info with {brackets}<|/info|>\nContent: with 'quotes''}"
194
+ assert formatted == expected
195
+
196
+
197
+ def test_empty_sections(xml_style_config_without_page_number, json_style_config):
198
+ chunk = ContentChunk(
199
+ id="1",
200
+ order=1,
201
+ text="Just plain text without any sections",
202
+ start_page=None,
203
+ end_page=None,
204
+ )
205
+
206
+ # Test XML style
207
+ xml_formatted = format_chunk(1, chunk, xml_style_config_without_page_number)
208
+ assert xml_formatted == "<source1>Just plain text without any sections</source1>"
209
+
210
+ # Test JSON style
211
+ json_formatted = format_chunk(1, chunk, json_style_config)
212
+ assert (
213
+ json_formatted
214
+ == "{'source_number': 1, 'content': 'Just plain text without any sections'}"
215
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 0.8.3
3
+ Version: 0.8.5
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Martin Fadler
@@ -113,6 +113,12 @@ All notable changes to this project will be documented in this file.
113
113
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
114
114
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
115
115
 
116
+ ## [0.8.5] - 2025-08-06
117
+ - Refactored tools to be in the tool-kit
118
+
119
+ ## [0.8.4] - 2025-08-06
120
+ - Make unique settings compatible with legacy environment variables
121
+
116
122
  ## [0.8.3] - 2025-08-05
117
123
  - Expose threshold field for search.
118
124
 
@@ -10,8 +10,8 @@ unique_toolkit/app/init_logging.py,sha256=Sh26SRxOj8i8dzobKhYha2lLrkrMTHfB1V4jR3
10
10
  unique_toolkit/app/init_sdk.py,sha256=5_oDoETr6akwYyBCb0ivTdMNu3SVgPSkrXcDS6ELyY8,2269
11
11
  unique_toolkit/app/performance/async_tasks.py,sha256=H0l3OAcosLwNHZ8d2pd-Di4wHIXfclEvagi5kfqLFPA,1941
12
12
  unique_toolkit/app/performance/async_wrapper.py,sha256=yVVcRDkcdyfjsxro-N29SBvi-7773wnfDplef6-y8xw,1077
13
- unique_toolkit/app/schemas.py,sha256=JdC2rNVPRrr6QhGMZweE0ID760onbRY2oq9m1LVFego,7429
14
- unique_toolkit/app/unique_settings.py,sha256=YwKXKKSrLSoNk5kow5ChC0uOqii37gd3ttFL4rSAVF4,4443
13
+ unique_toolkit/app/schemas.py,sha256=J584RzwzIVSsdZyq0uVLI6efxIpWiMPKNz_IjIoOrxo,7432
14
+ unique_toolkit/app/unique_settings.py,sha256=Gn8qxy_hNraVTTlP4wfZJzgxPU8cU6s84Uw6FK6ixGg,5946
15
15
  unique_toolkit/app/verification.py,sha256=GxFFwcJMy25fCA_Xe89wKW7bgqOu8PAs5y8QpHF0GSc,3861
16
16
  unique_toolkit/chat/__init__.py,sha256=LRs2G-JTVuci4lbtHTkVUiNcZcSR6uqqfnAyo7af6nY,619
17
17
  unique_toolkit/chat/constants.py,sha256=05kq6zjqUVB2d6_P7s-90nbljpB3ryxwCI-CAz0r2O4,83
@@ -47,8 +47,8 @@ unique_toolkit/evaluators/hallucination/utils.py,sha256=gO2AOzDQwVTev2_5vDKgJ9A6
47
47
  unique_toolkit/evaluators/output_parser.py,sha256=eI72qkzK1dZyUvnfP2SOAQCGBj_-PwX5wy_aLPMsJMY,883
48
48
  unique_toolkit/evaluators/schemas.py,sha256=Jaue6Uhx75X1CyHKWj8sT3RE1JZXTqoLtfLt2xQNCX8,2507
49
49
  unique_toolkit/framework_utilities/langchain/client.py,sha256=Msfmr7uezwqagyRJ2zjWbQRFqzDExWYK0y5KLEnDNqM,1329
50
- unique_toolkit/framework_utilities/langchain/history.py,sha256=8ejA0utPUIlX4z8gtX9IkVFiooY-vOT1UcjI_MoJaAU,638
51
- unique_toolkit/framework_utilities/openai/client.py,sha256=Zs5zxFbRfa0XrlbZvhGf-GpHomKLBJx0D28iowk1Eek,1236
50
+ unique_toolkit/framework_utilities/langchain/history.py,sha256=R9RuCeSFNaUO3OZ0G_LmIC4gmOCIANcl91MfyWLnZ1c,650
51
+ unique_toolkit/framework_utilities/openai/client.py,sha256=IasxPXlVJHIsZdXHin7yq-5tO4RNLUu9cEuhrgb4ghE,1205
52
52
  unique_toolkit/framework_utilities/openai/message_builder.py,sha256=meJVGPaSQ6xEafNZtACujcD0KXdiSYGTNiv02FSJULE,3834
53
53
  unique_toolkit/framework_utilities/utils.py,sha256=JK7g2yMfEx3eMprug26769xqNpS5WJcizf8n2zWMBng,789
54
54
  unique_toolkit/language_model/__init__.py,sha256=lRQyLlbwHbNFf4-0foBU13UGb09lwEeodbVsfsSgaCk,1971
@@ -58,10 +58,11 @@ unique_toolkit/language_model/functions.py,sha256=WhgHbJgz4Z2aZt9TLdOpI0PGyYWA5R
58
58
  unique_toolkit/language_model/infos.py,sha256=Abxcw-l7UXkBohxZsigpNz0OUUCtDf404LLr7R-ys4E,33757
59
59
  unique_toolkit/language_model/prompt.py,sha256=JSawaLjQg3VR-E2fK8engFyJnNdk21zaO8pPIodzN4Q,3991
60
60
  unique_toolkit/language_model/reference.py,sha256=nkX2VFz-IrUz8yqyc3G5jUMNwrNpxITBrMEKkbqqYoI,8583
61
- unique_toolkit/language_model/schemas.py,sha256=AeuDRJFblGzEYcEMyrlxpOPk12Di3J45I9rT2xZrhEU,14332
61
+ unique_toolkit/language_model/schemas.py,sha256=r6c_lJ9Gl9wvY-N0FlmyFZjv5vPSc6CurFhpyST1Z5Y,14762
62
62
  unique_toolkit/language_model/service.py,sha256=zlvC_t9T1wixwcGDPRxl6yYniaKl2725NxWrbW51jUs,11290
63
63
  unique_toolkit/language_model/utils.py,sha256=bPQ4l6_YO71w-zaIPanUUmtbXC1_hCvLK0tAFc3VCRc,1902
64
64
  unique_toolkit/protocols/support.py,sha256=V15WEIFKVMyF1QCnR8vIi4GrJy4dfTCB6d6JlqPZ58o,2341
65
+ unique_toolkit/reference_manager/reference_manager.py,sha256=FNCW4CQSsimS8UG7OTdu4-JNQXUMhPrOfRuKAbK9vvE,2305
65
66
  unique_toolkit/short_term_memory/__init__.py,sha256=2mI3AUrffgH7Yt-xS57EGqnHf7jnn6xquoKEhJqk3Wg,185
66
67
  unique_toolkit/short_term_memory/constants.py,sha256=698CL6-wjup2MvU19RxSmQk3gX7aqW_OOpZB7sbz_Xg,34
67
68
  unique_toolkit/short_term_memory/functions.py,sha256=3WiK-xatY5nh4Dr5zlDUye1k3E6kr41RiscwtTplw5k,4484
@@ -69,11 +70,19 @@ unique_toolkit/short_term_memory/schemas.py,sha256=OhfcXyF6ACdwIXW45sKzjtZX_gkcJ
69
70
  unique_toolkit/short_term_memory/service.py,sha256=5PeVBu1ZCAfyDb2HLVvlmqSbyzBBuE9sI2o9Aajqjxg,8884
70
71
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
72
  unique_toolkit/smart_rules/compile.py,sha256=cxWjb2dxEI2HGsakKdVCkSNi7VK9mr08w5sDcFCQyWI,9553
72
- unique_toolkit/tools/tool_definitions.py,sha256=YYu53vXMJBeJtuSU1L_FJBsiN52LSA5LIDt9O-1HBgE,4500
73
- unique_toolkit/tools/tool_definitionsV2.py,sha256=yjLmP85pFGd1QtIVMC3oLQPSQ2NckBj9hIihjIr2FZg,5728
74
- unique_toolkit/tools/tool_factory.py,sha256=ux11jd7Oobb-6eBeS51T-tviH14k6HKqsKmljA7h6qA,879
75
- unique_toolkit/tools/tool_progress_reporter.py,sha256=AyPdgxpd48qotJyPB8qJ7h7ghiv2w2EK8nlyqQVFRt4,8048
76
- unique_toolkit-0.8.3.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
77
- unique_toolkit-0.8.3.dist-info/METADATA,sha256=UEfARrL_5zaX43AazPC7fxsW53RVJO0lwJAOlzc3hUQ,26086
78
- unique_toolkit-0.8.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
79
- unique_toolkit-0.8.3.dist-info/RECORD,,
73
+ unique_toolkit/tools/agent_chunks_handler.py,sha256=ORjC22ulfHTfPxUHmU7QU0H53j3AdLmt1a0opeI91V8,1809
74
+ unique_toolkit/tools/config.py,sha256=9bYxdDuUPmAxhYyIdLbmXLzX1X2AUw--_WISQxQ4G2U,3003
75
+ unique_toolkit/tools/factory.py,sha256=vxxchbPTrk2lVjSMdpcFN-6FRcMLiy-NgHHS3w0wYCA,1271
76
+ unique_toolkit/tools/schemas.py,sha256=C9caE0EZNS6iGBPz2fsW5_Bao4GGGbAOda5D-XjnAQ0,4743
77
+ 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
80
+ unique_toolkit/tools/tool_progress_reporter.py,sha256=j6iVTpoLU_PjLwoK6fpIy9vmX_MLWF_-_v-nTDUcwas,7954
81
+ unique_toolkit/tools/utils/execution/execution.py,sha256=vjG2Y6awsGNtlvyQAGCTthQ5thWHYnn-vzZXaYLb3QE,7922
82
+ unique_toolkit/tools/utils/source_handling/schema.py,sha256=pvNhtL2daDLpCVIQpfdn6R35GvKmITVLXjZNLAwpgUE,871
83
+ unique_toolkit/tools/utils/source_handling/source_formatting.py,sha256=C7uayNbdkNVJdEARA5CENnHtNY1SU6etlaqbgHNyxaQ,9152
84
+ unique_toolkit/tools/utils/source_handling/tests/test_source_formatting.py,sha256=zu3AJnYH9CMqZPrxKEH3IgI-fM3nlvIBuspJG6W6B18,6978
85
+ unique_toolkit-0.8.5.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
86
+ unique_toolkit-0.8.5.dist-info/METADATA,sha256=LJBjcScwRSwqR65wI1LGrYeoPOBn69r2jCHy2NA0ma0,26245
87
+ unique_toolkit-0.8.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
88
+ unique_toolkit-0.8.5.dist-info/RECORD,,
@@ -1,145 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from enum import StrEnum
3
- from typing import Any, Generic, List, Self, TypeVar
4
- from unique_toolkit.language_model import LanguageModelToolDescription
5
- from typing_extensions import deprecated
6
- # import baseModel from pedantic
7
- from unique_toolkit.language_model import LanguageModelFunction
8
- from pydantic import BaseModel, Field, model_validator, root_validator
9
-
10
- from unique_toolkit.unique_toolkit.app.schemas import ChatEvent
11
- from unique_toolkit.unique_toolkit.tools.tool_progress_reporter import ToolProgressReporter
12
-
13
- class ToolSelectionPolicy(StrEnum):
14
- """Determine the usage policy of tools."""
15
-
16
- FORCED_BY_DEFAULT = "ForcedByDefault"
17
- ON_BY_DEFAULT = "OnByDefault"
18
- BY_USER = "ByUser"
19
-
20
- class UqToolName(StrEnum):
21
- WEB_SEARCH = "WebSearch"
22
- INTERNAL_SEARCH = "InternalSearch"
23
- DOCUMENT_SUMMARIZER = "DocumentSummarizer"
24
- CHART_GENERATOR = "ChartGenerator"
25
- DOCUMENT_GENERATOR = "DocumentGenerator"
26
- DOCUMENT_PARSER = "DocumentParser"
27
- IMAGE_CONTENT = "ImageContent"
28
- TABLE_SEARCH = "TableSearch"
29
- BAR_CHART = "BarChart"
30
- LINE_CHART = "LineChart"
31
- PIE_CHART = "PieChart"
32
- BASE_TOOL = "BaseTool"
33
-
34
-
35
- class BaseToolConfig(BaseModel):
36
- pass
37
-
38
-
39
- ConfigType = TypeVar("ConfigType", bound=BaseToolConfig)
40
-
41
-
42
- class ToolSettings(Generic[ConfigType]):
43
- configuration: ConfigType
44
- display_name: str
45
- icon: str
46
- selection_policy: ToolSelectionPolicy = Field(
47
- default=ToolSelectionPolicy.BY_USER,
48
- )
49
- is_exclusive: bool = Field(default=False)
50
- is_enabled: bool = Field(default=True)
51
-
52
- @classmethod
53
- def from_service_dict(cls, service_dict: dict[str, Any]) -> Self | None:
54
- try:
55
- return cls(**service_dict)
56
- except (ValueError, TypeError) as e:
57
- print(e)
58
- return None
59
-
60
-
61
- class ToolCallResponse(BaseModel):
62
- id: str
63
- name: str
64
- debug_info: dict = {}
65
-
66
-
67
- class ToolPromptInstructions(BaseModel):
68
- system_prompt: str = Field(
69
- default="",
70
- description=("Helps the LLM understand how to use the tool. "
71
- "This is injected into the system prompt."
72
- "This might not be needed for every tool but some of the work better with user prompt "
73
- "instructions while others work better with system prompt instructions."),
74
- )
75
-
76
- user_prompt: str = Field(
77
- default="",
78
- description=("Helps the LLM understand how to use the tool. "
79
- "This is injected into the user prompt. "
80
- "This might not be needed for every tool but some of the work better with user prompt "
81
- "instructions while others work better with system prompt instructions.")
82
- )
83
-
84
- system_prompt_tool_chosen: str = Field(
85
- default="",
86
- description=("Once the tool is chosen, this is injected into the system prompt"
87
- " to help the LLM understand how work with the tools results."),
88
- )
89
-
90
- user_prompt_tool_chosen: str = Field(
91
- default="",
92
- description=("Once the tool is chosen, this is injected into the user prompt "
93
- "to help the LLM understand how to work with the tools results."),
94
- )
95
-
96
-
97
- class Tool(ABC, Generic[ConfigType]):
98
- name: str
99
-
100
- def tool_description(self) -> LanguageModelToolDescription:
101
- raise NotImplementedError
102
-
103
-
104
- def get_prompt_instructions(self) -> ToolPromptInstructions:
105
- return ToolPromptInstructions(
106
- system_prompt="",
107
- user_prompt="",
108
- system_prompt_tool_chosen="",
109
- user_prompt_tool_chosen="",
110
- )
111
-
112
-
113
- def is_exclusive(self) -> bool:
114
- return self.settings.is_exclusive
115
-
116
- def is_enabled(self) -> bool:
117
- return self.settings.is_enabled
118
-
119
- def display_name(self) -> str:
120
- return self.settings.display_name
121
-
122
- def icon(self) -> str:
123
- return self.settings.icon
124
-
125
- def tool_selection_policy(self) -> ToolSelectionPolicy:
126
- return self.settings.selection_policy
127
-
128
-
129
- @abstractmethod
130
- async def run(self, tool_call: LanguageModelFunction) -> ToolCallResponse:
131
- raise NotImplementedError
132
-
133
-
134
-
135
- def __init__(
136
- self,
137
- settings: ToolSettings[ConfigType],
138
- event: ChatEvent,
139
- tool_progress_reporter: ToolProgressReporter
140
- ):
141
- self.settings = settings
142
- self.tool_progress_reporter = tool_progress_reporter
143
- self.event = event
144
-
145
-
@@ -1,137 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from enum import StrEnum
3
- from typing import Any, Generic, List, Self, TypeVar
4
- from unique_toolkit.language_model import LanguageModelToolDescription
5
- from typing_extensions import deprecated
6
- # import baseModel from pedantic
7
- from unique_toolkit.language_model import LanguageModelFunction
8
- from pydantic import BaseModel, Field, model_validator, root_validator
9
-
10
- from unique_toolkit.unique_toolkit.app.schemas import ChatEvent
11
- from unique_toolkit.unique_toolkit.tools.tool_definitions import BaseToolConfig, Tool, ToolCallResponse, ToolPromptInstructions, ToolSettings
12
- from unique_toolkit.unique_toolkit.tools.tool_progress_reporter import ToolProgressReporter
13
-
14
-
15
- class BaseToolConfigV2(BaseToolConfig):
16
- class ToolCallConfig(BaseModel):
17
- description: str = Field(
18
- default="Base",
19
- description="The tool description must be set by subclasses",
20
- )
21
-
22
- parameters: type[BaseModel] = Field(
23
- default=BaseModel,
24
- description="The tool parameters configuration must be set by subclasses",
25
- )
26
-
27
- class PromptInstructionsConfig(BaseModel):
28
- system_prompt: str = Field(
29
- default="",
30
- description=("Helps the LLM understand how to use the tool. "
31
- "This is injected into the system prompt."
32
- "This might not be needed for every tool but some of the work better with user prompt "
33
- "instructions while others work better with system prompt instructions."),
34
- )
35
-
36
- user_prompt: str = Field(
37
- default="",
38
- description=("Helps the LLM understand how to use the tool. "
39
- "This is injected into the user prompt. "
40
- "This might not be needed for every tool but some of the work better with user prompt "
41
- "instructions while others work better with system prompt instructions.")
42
- )
43
-
44
- system_prompt_tool_chosen: str = Field(
45
- default="",
46
- description=("Once the tool is chosen, this is injected into the system prompt"
47
- " to help the LLM understand how work with the tools results."),
48
- )
49
-
50
- user_prompt_tool_chosen: str = Field(
51
- default="",
52
- description=("Once the tool is chosen, this is injected into the user prompt "
53
- "to help the LLM understand how to work with the tools results."),
54
- )
55
-
56
- tool_call: ToolCallConfig = Field(
57
- default_factory=ToolCallConfig,
58
- description="Configuration for the tool, including description and parameters",
59
- )
60
-
61
- prompts: PromptInstructionsConfig = Field(
62
- default_factory=PromptInstructionsConfig,
63
- description="Configuration for prompts related to the tool",
64
- )
65
-
66
- # This makes sure that the settings are all present in all subclasses and that they define a default value.
67
- @model_validator(mode="after")
68
- def validate_tool_description(cls):
69
- if cls.__class__ is BaseToolConfig:
70
- return cls # Skip validation for the base class
71
- if cls.tool_call.description == "Base":
72
- raise ValueError(
73
- f"Subclass {cls.__class__.__name__} must define a default value for 'tool_description'."
74
- )
75
- if cls.tool_call.parameters == BaseModel:
76
- raise ValueError(
77
- f"Subclass {cls.__class__.__name__} must define a default value for 'tool_parameters_config'."
78
- )
79
- if cls.prompts.system_prompt == "":
80
- raise ValueError(
81
- f"Subclass {cls.__class__.__name__} must define a default value for 'system_prompt_base_instructions'."
82
- )
83
- if cls.prompts.user_prompt == "":
84
- raise ValueError(
85
- f"Subclass {cls.__class__.__name__} must define a default value for 'user_prompt_base_instructions'."
86
- )
87
- if cls.prompts.system_prompt_tool_chosen == "":
88
- raise ValueError(
89
- f"Subclass {cls.__class__.__name__} must define a default value for 'system_prompt_tool_chosen_instructions'."
90
- )
91
- if cls.prompts.user_prompt_tool_chosen == "":
92
- raise ValueError(
93
- f"Subclass {cls.__class__.__name__} must define a default value for 'user_prompt_tool_chosen_instructions'."
94
- )
95
- return cls
96
-
97
-
98
- ConfigTypeV2 = TypeVar("ConfigTypeV2", bound=BaseToolConfigV2)
99
-
100
-
101
-
102
- class ToolV2(Tool[ConfigTypeV2]):
103
- name: str
104
-
105
- def tool_description(self) -> LanguageModelToolDescription:
106
- return LanguageModelToolDescription(
107
- name=self.name,
108
- description=self.settings.configuration.tool_call.description,
109
- parameters=self.settings.configuration.tool_call.parameters,
110
- )
111
-
112
- def get_prompt_instructions(self) -> ToolPromptInstructions:
113
- return ToolPromptInstructions(
114
- system_prompt=self.settings.configuration.prompts.system_prompt,
115
- user_prompt=self.settings.configuration.prompts.user_prompt,
116
- system_prompt_tool_chosen=self.settings.configuration.prompts.system_prompt_tool_chosen,
117
- user_prompt_tool_chosen=self.settings.configuration.prompts.user_prompt_tool_chosen
118
- )
119
-
120
-
121
- @abstractmethod
122
- async def run(self, tool_call: LanguageModelFunction) -> ToolCallResponse:
123
- raise NotImplementedError
124
-
125
-
126
-
127
- def __init__(
128
- self,
129
- settings: ToolSettings[ConfigTypeV2],
130
- event: ChatEvent,
131
- tool_progress_reporter: ToolProgressReporter
132
- ):
133
- self.settings = settings
134
- self.tool_progress_reporter = tool_progress_reporter
135
- self.event = event
136
-
137
-