unique_toolkit 1.17.3__py3-none-any.whl → 1.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of unique_toolkit might be problematic. Click here for more details.
- unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py +56 -9
- unique_toolkit/agentic/tools/a2a/postprocessing/_display.py +5 -1
- unique_toolkit/agentic/tools/a2a/postprocessing/postprocessor.py +17 -1
- unique_toolkit/agentic/tools/a2a/tool/config.py +10 -0
- unique_toolkit/agentic/tools/a2a/tool/service.py +2 -1
- unique_toolkit/agentic/tools/utils/__init__.py +18 -0
- {unique_toolkit-1.17.3.dist-info → unique_toolkit-1.18.0.dist-info}/METADATA +6 -1
- {unique_toolkit-1.17.3.dist-info → unique_toolkit-1.18.0.dist-info}/RECORD +10 -10
- {unique_toolkit-1.17.3.dist-info → unique_toolkit-1.18.0.dist-info}/LICENSE +0 -0
- {unique_toolkit-1.17.3.dist-info → unique_toolkit-1.18.0.dist-info}/WHEEL +0 -0
|
@@ -3,6 +3,7 @@ from typing import override
|
|
|
3
3
|
|
|
4
4
|
import unique_sdk
|
|
5
5
|
from jinja2 import Template
|
|
6
|
+
from pydantic import BaseModel
|
|
6
7
|
from typing_extensions import TypedDict
|
|
7
8
|
|
|
8
9
|
from unique_toolkit.agentic.evaluation.evaluation_manager import Evaluation
|
|
@@ -21,6 +22,7 @@ from unique_toolkit.agentic.tools.a2a.evaluation.config import (
|
|
|
21
22
|
SubAgentEvaluationServiceConfig,
|
|
22
23
|
)
|
|
23
24
|
from unique_toolkit.agentic.tools.a2a.tool import SubAgentTool
|
|
25
|
+
from unique_toolkit.agentic.tools.utils import failsafe
|
|
24
26
|
from unique_toolkit.chat.schemas import (
|
|
25
27
|
ChatMessageAssessmentLabel,
|
|
26
28
|
ChatMessageAssessmentStatus,
|
|
@@ -38,7 +40,27 @@ class _SubAgentToolInfo(TypedDict):
|
|
|
38
40
|
display_name: str
|
|
39
41
|
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
_NO_ASSESSMENTS_FOUND = "NO_ASSESSMENTS_FOUND"
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class _SingleAssessmentData(BaseModel):
|
|
47
|
+
name: str
|
|
48
|
+
explanation: str
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _format_single_assessment_found(name: str, explanation: str) -> str:
|
|
52
|
+
return _SingleAssessmentData(name=name, explanation=explanation).model_dump_json()
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@failsafe(failure_return_value=False)
|
|
56
|
+
def _is_single_assessment_found(value: str) -> bool:
|
|
57
|
+
_ = _SingleAssessmentData.model_validate_json(value)
|
|
58
|
+
return True
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _parse_single_assessment_found(value: str) -> tuple[str, str]:
|
|
62
|
+
data = _SingleAssessmentData.model_validate_json(value)
|
|
63
|
+
return data.name, data.explanation
|
|
42
64
|
|
|
43
65
|
|
|
44
66
|
class SubAgentEvaluationService(Evaluation):
|
|
@@ -99,15 +121,36 @@ class SubAgentEvaluationService(Evaluation):
|
|
|
99
121
|
|
|
100
122
|
sub_agents_display_data.append(data)
|
|
101
123
|
|
|
124
|
+
# No valid assessments found
|
|
102
125
|
if len(sub_agents_display_data) == 0:
|
|
103
126
|
logger.warning("No valid sub agent assessments found")
|
|
104
127
|
|
|
105
128
|
return EvaluationMetricResult(
|
|
106
129
|
name=self.get_name(),
|
|
107
|
-
|
|
130
|
+
# This is a trick to be able to indicate to `evaluation_metric_to_assessment`
|
|
131
|
+
# that no valid assessments were found
|
|
132
|
+
value=_NO_ASSESSMENTS_FOUND,
|
|
108
133
|
reason="No sub agents assessments found",
|
|
109
134
|
)
|
|
110
135
|
|
|
136
|
+
# Only one valid assessment found, no need to perform summarization
|
|
137
|
+
if (
|
|
138
|
+
len(sub_agents_display_data) == 1
|
|
139
|
+
and len(sub_agents_display_data[0]["assessments"]) == 1
|
|
140
|
+
):
|
|
141
|
+
assessment = sub_agents_display_data[0]["assessments"][0]
|
|
142
|
+
explanation = assessment["explanation"] or ""
|
|
143
|
+
name = sub_agents_display_data[0]["name"]
|
|
144
|
+
label = assessment["label"]
|
|
145
|
+
|
|
146
|
+
return EvaluationMetricResult(
|
|
147
|
+
name=self.get_name(),
|
|
148
|
+
value=label,
|
|
149
|
+
# This is a trick to be able to pass the display name to the UI in `evaluation_metric_to_assessment`
|
|
150
|
+
reason=_format_single_assessment_found(name, explanation),
|
|
151
|
+
is_positive=label == ChatMessageAssessmentLabel.GREEN,
|
|
152
|
+
)
|
|
153
|
+
|
|
111
154
|
reason = await self._get_reason(sub_agents_display_data)
|
|
112
155
|
|
|
113
156
|
return EvaluationMetricResult(
|
|
@@ -121,7 +164,7 @@ class SubAgentEvaluationService(Evaluation):
|
|
|
121
164
|
async def evaluation_metric_to_assessment(
|
|
122
165
|
self, evaluation_result: EvaluationMetricResult
|
|
123
166
|
) -> EvaluationAssessmentMessage:
|
|
124
|
-
if evaluation_result.value ==
|
|
167
|
+
if evaluation_result.value == _NO_ASSESSMENTS_FOUND:
|
|
125
168
|
return EvaluationAssessmentMessage(
|
|
126
169
|
status=ChatMessageAssessmentStatus.DONE,
|
|
127
170
|
explanation="No valid sub agents assessments found to consolidate.",
|
|
@@ -130,6 +173,16 @@ class SubAgentEvaluationService(Evaluation):
|
|
|
130
173
|
type=self.get_assessment_type(),
|
|
131
174
|
)
|
|
132
175
|
|
|
176
|
+
if _is_single_assessment_found(evaluation_result.reason):
|
|
177
|
+
name, reason = _parse_single_assessment_found(evaluation_result.reason)
|
|
178
|
+
return EvaluationAssessmentMessage(
|
|
179
|
+
status=ChatMessageAssessmentStatus.DONE,
|
|
180
|
+
explanation=reason,
|
|
181
|
+
title=name,
|
|
182
|
+
label=evaluation_result.value, # type: ignore
|
|
183
|
+
type=self.get_assessment_type(),
|
|
184
|
+
)
|
|
185
|
+
|
|
133
186
|
return EvaluationAssessmentMessage(
|
|
134
187
|
status=ChatMessageAssessmentStatus.DONE,
|
|
135
188
|
explanation=evaluation_result.reason,
|
|
@@ -182,12 +235,6 @@ class SubAgentEvaluationService(Evaluation):
|
|
|
182
235
|
)
|
|
183
236
|
|
|
184
237
|
async def _get_reason(self, sub_agents_display_data: list[dict]) -> str:
|
|
185
|
-
if (
|
|
186
|
-
len(sub_agents_display_data) == 1
|
|
187
|
-
and len(sub_agents_display_data[0]["assessments"]) == 1
|
|
188
|
-
):
|
|
189
|
-
return sub_agents_display_data[0]["assessments"][0]["explanation"] or ""
|
|
190
|
-
|
|
191
238
|
messages = (
|
|
192
239
|
MessagesBuilder()
|
|
193
240
|
.system_message_append(self._config.summarization_system_message)
|
|
@@ -94,13 +94,17 @@ def _get_display_template(
|
|
|
94
94
|
assistant_id_placeholder, "{%s}" % answer_placeholder, sep="\n\n"
|
|
95
95
|
) # Double line break is needed for markdown formatting
|
|
96
96
|
|
|
97
|
+
template = _add_line_break(template, before=True, after=False)
|
|
98
|
+
|
|
97
99
|
if add_quote_border:
|
|
98
100
|
template = _wrap_with_quote_border(template)
|
|
99
101
|
|
|
100
102
|
match mode:
|
|
101
103
|
case SubAgentResponseDisplayMode.DETAILS_OPEN:
|
|
102
104
|
template = _wrap_with_details_tag(
|
|
103
|
-
template,
|
|
105
|
+
template,
|
|
106
|
+
"open",
|
|
107
|
+
display_name_placeholder,
|
|
104
108
|
)
|
|
105
109
|
case SubAgentResponseDisplayMode.DETAILS_CLOSED:
|
|
106
110
|
template = _wrap_with_details_tag(
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
import logging
|
|
2
3
|
import re
|
|
3
4
|
from typing import TypedDict, override
|
|
4
5
|
|
|
5
6
|
import unique_sdk
|
|
7
|
+
from pydantic import BaseModel, Field
|
|
6
8
|
|
|
9
|
+
from unique_toolkit._common.pydantic_helpers import get_configuration_dict
|
|
7
10
|
from unique_toolkit.agentic.postprocessor.postprocessor_manager import Postprocessor
|
|
8
11
|
from unique_toolkit.agentic.tools.a2a.postprocessing._display import (
|
|
9
12
|
_build_sub_agent_answer_display,
|
|
@@ -37,12 +40,21 @@ class _SubAgentToolInfo(TypedDict):
|
|
|
37
40
|
responses: dict[int, _SubAgentMessageInfo]
|
|
38
41
|
|
|
39
42
|
|
|
43
|
+
class SubAgentResponsesPostprocessorConfig(BaseModel):
|
|
44
|
+
model_config = get_configuration_dict()
|
|
45
|
+
|
|
46
|
+
sleep_time_before_update: float = Field(
|
|
47
|
+
default=0.5, description="Time to sleep before updating the main agent message."
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
|
|
40
51
|
class SubAgentResponsesPostprocessor(Postprocessor):
|
|
41
52
|
def __init__(
|
|
42
53
|
self,
|
|
43
54
|
user_id: str,
|
|
44
55
|
company_id: str,
|
|
45
56
|
main_agent_chat_id: str,
|
|
57
|
+
config: SubAgentResponsesPostprocessorConfig | None = None,
|
|
46
58
|
) -> None:
|
|
47
59
|
super().__init__(name=self.__class__.__name__)
|
|
48
60
|
|
|
@@ -52,6 +64,7 @@ class SubAgentResponsesPostprocessor(Postprocessor):
|
|
|
52
64
|
|
|
53
65
|
self._assistant_id_to_tool_info: dict[str, _SubAgentToolInfo] = {}
|
|
54
66
|
self._main_agent_message: SpaceMessage | None = None
|
|
67
|
+
self._config = config or SubAgentResponsesPostprocessorConfig()
|
|
55
68
|
|
|
56
69
|
@override
|
|
57
70
|
async def run(self, loop_response: LanguageModelStreamResponse) -> None:
|
|
@@ -60,6 +73,9 @@ class SubAgentResponsesPostprocessor(Postprocessor):
|
|
|
60
73
|
company_id=self._company_id,
|
|
61
74
|
chat_id=self._main_agent_chat_id,
|
|
62
75
|
)
|
|
76
|
+
await asyncio.sleep(
|
|
77
|
+
self._config.sleep_time_before_update
|
|
78
|
+
) # Frontend rendering issues
|
|
63
79
|
|
|
64
80
|
@override
|
|
65
81
|
def apply_postprocessing_to_response(
|
|
@@ -125,7 +141,7 @@ class SubAgentResponsesPostprocessor(Postprocessor):
|
|
|
125
141
|
)
|
|
126
142
|
|
|
127
143
|
loop_response.message.text = (
|
|
128
|
-
"
|
|
144
|
+
"<br>\n\n".join(answers) + "<br>\n\n" + loop_response.message.text.strip()
|
|
129
145
|
)
|
|
130
146
|
|
|
131
147
|
return True
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Literal
|
|
2
|
+
|
|
1
3
|
from pydantic import Field
|
|
2
4
|
|
|
3
5
|
from unique_toolkit._common.pydantic_helpers import get_configuration_dict
|
|
@@ -27,6 +29,10 @@ class SubAgentToolConfig(BaseToolConfig):
|
|
|
27
29
|
default=True,
|
|
28
30
|
description="Whether this sub agent's references should be used in the main agent's response.",
|
|
29
31
|
)
|
|
32
|
+
forced_tools: list[str] | None = Field(
|
|
33
|
+
default=None,
|
|
34
|
+
description="The list of tool names that will be forced to be called for this sub-agent.",
|
|
35
|
+
)
|
|
30
36
|
|
|
31
37
|
tool_description_for_system_prompt: str = Field(
|
|
32
38
|
default="",
|
|
@@ -61,3 +67,7 @@ class SubAgentToolConfig(BaseToolConfig):
|
|
|
61
67
|
default=120.0,
|
|
62
68
|
description="Maximum time in seconds to wait for the sub-agent response before timing out.",
|
|
63
69
|
)
|
|
70
|
+
stop_condition: Literal["stoppedStreamingAt", "completedAt"] = Field(
|
|
71
|
+
default="completedAt",
|
|
72
|
+
description="The condition that will be used to stop the polling for the sub-agent response.",
|
|
73
|
+
)
|
|
@@ -282,8 +282,9 @@ class SubAgentTool(Tool[SubAgentToolConfig]):
|
|
|
282
282
|
text=tool_user_message,
|
|
283
283
|
chat_id=chat_id,
|
|
284
284
|
poll_interval=self.config.poll_interval,
|
|
285
|
+
tool_choices=self.config.forced_tools,
|
|
285
286
|
max_wait=self.config.max_wait,
|
|
286
|
-
stop_condition=
|
|
287
|
+
stop_condition=self.config.stop_condition,
|
|
287
288
|
)
|
|
288
289
|
except TimeoutError as e:
|
|
289
290
|
await self._notify_progress(
|
|
@@ -1 +1,19 @@
|
|
|
1
1
|
"""Utilities for tools."""
|
|
2
|
+
|
|
3
|
+
from unique_toolkit.agentic.tools.utils.execution.execution import (
|
|
4
|
+
Result,
|
|
5
|
+
SafeTaskExecutor,
|
|
6
|
+
failsafe,
|
|
7
|
+
failsafe_async,
|
|
8
|
+
safe_execute,
|
|
9
|
+
safe_execute_async,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"failsafe",
|
|
14
|
+
"failsafe_async",
|
|
15
|
+
"safe_execute",
|
|
16
|
+
"safe_execute_async",
|
|
17
|
+
"SafeTaskExecutor",
|
|
18
|
+
"Result",
|
|
19
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: unique_toolkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.18.0
|
|
4
4
|
Summary:
|
|
5
5
|
License: Proprietary
|
|
6
6
|
Author: Cedric Klinkert
|
|
@@ -118,6 +118,11 @@ All notable changes to this project will be documented in this file.
|
|
|
118
118
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
119
119
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
120
120
|
|
|
121
|
+
## [1.18.0] - 2025-10-27
|
|
122
|
+
- Temporary fix to rendering of sub agent responses.
|
|
123
|
+
- Add config option `stop_condition` to `SubAgentToolConfig`
|
|
124
|
+
- Add config option `tool_choices` to `SubAgentToolConfig`
|
|
125
|
+
- Make sub agent evaluation use the name of the sub agent name if only one assessment is valid
|
|
121
126
|
|
|
122
127
|
## [1.17.3] - 2025-10-27
|
|
123
128
|
- Update Hallucination check citation regex parsing pattern
|
|
@@ -61,14 +61,14 @@ unique_toolkit/agentic/tools/a2a/config.py,sha256=6diTTSiS2prY294LfYozB-db2wmJ6j
|
|
|
61
61
|
unique_toolkit/agentic/tools/a2a/evaluation/__init__.py,sha256=_cR8uBwLbG7lyXoRskTpItzacgs4n23e2LeqClrytuc,354
|
|
62
62
|
unique_toolkit/agentic/tools/a2a/evaluation/_utils.py,sha256=GtcPAMWkwGwJ--hBxn35ow9jN0VKYx8h2qMUXR8DCho,1877
|
|
63
63
|
unique_toolkit/agentic/tools/a2a/evaluation/config.py,sha256=Ra5rzJArS3r8C7RTmzKB8cLEYh4w-u3pe_XLgul3GOA,2355
|
|
64
|
-
unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py,sha256
|
|
64
|
+
unique_toolkit/agentic/tools/a2a/evaluation/evaluator.py,sha256=-XDqkC2fLDFMkl8KZIefb1fl9dvlwug-uzcWmhil0vk,9144
|
|
65
65
|
unique_toolkit/agentic/tools/a2a/evaluation/summarization_user_message.j2,sha256=acP1YqD_sCy6DT0V2EIfhQTmaUKeqpeWNJ7RGgceo8I,271
|
|
66
66
|
unique_toolkit/agentic/tools/a2a/manager.py,sha256=FkO9jY7o8Td0t-HBkkatmxwhJGSJXmYkFYKFhPdbpMo,1674
|
|
67
67
|
unique_toolkit/agentic/tools/a2a/postprocessing/__init__.py,sha256=R90CSecxJrKH7TbwiMYPyTwsXUUmouL8fbEUlL4ee9Q,362
|
|
68
|
-
unique_toolkit/agentic/tools/a2a/postprocessing/_display.py,sha256=
|
|
68
|
+
unique_toolkit/agentic/tools/a2a/postprocessing/_display.py,sha256=rdWk-6M6V27v7G3dqaaDj1vXcgsFvDrHswFuSKQfd2I,5186
|
|
69
69
|
unique_toolkit/agentic/tools/a2a/postprocessing/_utils.py,sha256=JsWwylR2Ao_L0wk1UlhqeN2fTxPnrbhoi1klYHVBnLk,750
|
|
70
70
|
unique_toolkit/agentic/tools/a2a/postprocessing/config.py,sha256=hqo3vQZX63yXoLT7wN13vf0rC7qKiozKKfdkicYCQno,1061
|
|
71
|
-
unique_toolkit/agentic/tools/a2a/postprocessing/postprocessor.py,sha256=
|
|
71
|
+
unique_toolkit/agentic/tools/a2a/postprocessing/postprocessor.py,sha256=lEjJ1u-CTpoyDT7OFaBBOklONUCUU-CGsosHJRYUfkI,10335
|
|
72
72
|
unique_toolkit/agentic/tools/a2a/postprocessing/test/test_consolidate_references.py,sha256=0hlTbtqClyMqHNnZRRxETgjVhYrtRu3xUnZx0JSE-uo,28030
|
|
73
73
|
unique_toolkit/agentic/tools/a2a/postprocessing/test/test_display.py,sha256=Hn2GOsVhpCkpFV9Asvy_IyiYvCd88rxDzi0E_zt2kWc,37553
|
|
74
74
|
unique_toolkit/agentic/tools/a2a/postprocessing/test/test_postprocessor_reference_functions.py,sha256=GxSkkY-Xgd61Bk8sIRfEtkT9hqL1VgPLWrq-6XoB0rA,11360
|
|
@@ -76,8 +76,8 @@ unique_toolkit/agentic/tools/a2a/prompts.py,sha256=0ILHL_RAcT04gFm2d470j4Gho7PoJ
|
|
|
76
76
|
unique_toolkit/agentic/tools/a2a/tool/__init__.py,sha256=JIJKZBTLTA39OWhxoUd6uairxmqINur1Ex6iXDk9ef8,197
|
|
77
77
|
unique_toolkit/agentic/tools/a2a/tool/_memory.py,sha256=w8bxjokrqHQZgApd55b5rHXF-DpgJwaKTg4CvLBLamc,1034
|
|
78
78
|
unique_toolkit/agentic/tools/a2a/tool/_schema.py,sha256=wMwyunViTnxaURvenkATEvyfXn5LvLaP0HxbYqdZGls,158
|
|
79
|
-
unique_toolkit/agentic/tools/a2a/tool/config.py,sha256=
|
|
80
|
-
unique_toolkit/agentic/tools/a2a/tool/service.py,sha256=
|
|
79
|
+
unique_toolkit/agentic/tools/a2a/tool/config.py,sha256=NcrS0hzIeYvjv1oMobAAPlZrbTPPWhcPhi0jUHLFBTI,2903
|
|
80
|
+
unique_toolkit/agentic/tools/a2a/tool/service.py,sha256=Rutos0nmY4PhvO_ETlHr5mRdQFa2UuzSJWC2rmiAJng,10593
|
|
81
81
|
unique_toolkit/agentic/tools/agent_chunks_hanlder.py,sha256=x32Dp1Z8cVW5i-XzXbaMwX2KHPcNGmqEU-FB4AV9ZGo,1909
|
|
82
82
|
unique_toolkit/agentic/tools/config.py,sha256=QD83iy2xAJFyoPggYyLWq-MaSGSq00yS9iI31My1NBc,5387
|
|
83
83
|
unique_toolkit/agentic/tools/factory.py,sha256=A1Aliwx037UAk9ADiDsg0zjCWWnvzV_PxwJNoPTvW6c,1434
|
|
@@ -97,7 +97,7 @@ unique_toolkit/agentic/tools/test/test_tool_progress_reporter.py,sha256=dod5QPqg
|
|
|
97
97
|
unique_toolkit/agentic/tools/tool.py,sha256=m56VLxiHuKU2_J5foZp00xhm5lTxWEW7zRLGbIE9ssU,6744
|
|
98
98
|
unique_toolkit/agentic/tools/tool_manager.py,sha256=DtxJobe_7QKFe6CjnMhCP-mnKO6MjnZeDXsO3jBoC9w,16283
|
|
99
99
|
unique_toolkit/agentic/tools/tool_progress_reporter.py,sha256=ixud9VoHey1vlU1t86cW0-WTvyTwMxNSWBon8I11SUk,7955
|
|
100
|
-
unique_toolkit/agentic/tools/utils/__init__.py,sha256=
|
|
100
|
+
unique_toolkit/agentic/tools/utils/__init__.py,sha256=s75sjY5nrJchjLGs3MwSIqhDW08fFXIaX7eRQjFIA4s,346
|
|
101
101
|
unique_toolkit/agentic/tools/utils/execution/__init__.py,sha256=OHiKpqBnfhBiEQagKVWJsZlHv8smPp5OI4dFIexzibw,37
|
|
102
102
|
unique_toolkit/agentic/tools/utils/execution/execution.py,sha256=vjG2Y6awsGNtlvyQAGCTthQ5thWHYnn-vzZXaYLb3QE,7922
|
|
103
103
|
unique_toolkit/agentic/tools/utils/source_handling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -165,7 +165,7 @@ unique_toolkit/short_term_memory/service.py,sha256=5PeVBu1ZCAfyDb2HLVvlmqSbyzBBu
|
|
|
165
165
|
unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
166
166
|
unique_toolkit/smart_rules/compile.py,sha256=Ozhh70qCn2yOzRWr9d8WmJeTo7AQurwd3tStgBMPFLA,1246
|
|
167
167
|
unique_toolkit/test_utilities/events.py,sha256=_mwV2bs5iLjxS1ynDCjaIq-gjjKhXYCK-iy3dRfvO3g,6410
|
|
168
|
-
unique_toolkit-1.
|
|
169
|
-
unique_toolkit-1.
|
|
170
|
-
unique_toolkit-1.
|
|
171
|
-
unique_toolkit-1.
|
|
168
|
+
unique_toolkit-1.18.0.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
|
|
169
|
+
unique_toolkit-1.18.0.dist-info/METADATA,sha256=6XAUmwya1a8ILqkVKETFxYEaCF4p4Q3GfhRmgWO6tcI,38528
|
|
170
|
+
unique_toolkit-1.18.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
171
|
+
unique_toolkit-1.18.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|