unique_toolkit 2026.28.0.dev1__py3-none-any.whl → 2026.28.0.dev2__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/agentic/tools/experimental/__init__.py +6 -0
- unique_toolkit/agentic/tools/experimental/ask_user_tool/__init__.py +14 -0
- unique_toolkit/agentic/tools/experimental/ask_user_tool/config.py +138 -0
- unique_toolkit/agentic/tools/experimental/ask_user_tool/tool.py +149 -0
- unique_toolkit/elicitation/service.py +46 -0
- {unique_toolkit-2026.28.0.dev1.dist-info → unique_toolkit-2026.28.0.dev2.dist-info}/METADATA +2 -2
- {unique_toolkit-2026.28.0.dev1.dist-info → unique_toolkit-2026.28.0.dev2.dist-info}/RECORD +8 -5
- {unique_toolkit-2026.28.0.dev1.dist-info → unique_toolkit-2026.28.0.dev2.dist-info}/WHEEL +0 -0
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
from unique_toolkit.agentic.tools.experimental.ask_user_tool import (
|
|
2
|
+
AskUserTool,
|
|
3
|
+
AskUserToolConfig,
|
|
4
|
+
)
|
|
1
5
|
from unique_toolkit.agentic.tools.experimental.open_file_tool import (
|
|
2
6
|
OpenFileTool,
|
|
3
7
|
OpenFileToolRuntime,
|
|
@@ -19,6 +23,8 @@ from unique_toolkit.agentic.tools.experimental.todo import (
|
|
|
19
23
|
)
|
|
20
24
|
|
|
21
25
|
__all__ = [
|
|
26
|
+
"AskUserTool",
|
|
27
|
+
"AskUserToolConfig",
|
|
22
28
|
"DisplayMode",
|
|
23
29
|
"OpenFileTool",
|
|
24
30
|
"OpenFileToolRuntime",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from unique_toolkit.agentic.tools.experimental.ask_user_tool.config import (
|
|
2
|
+
AskUserToolConfig,
|
|
3
|
+
)
|
|
4
|
+
from unique_toolkit.agentic.tools.experimental.ask_user_tool.tool import (
|
|
5
|
+
AskUserTool,
|
|
6
|
+
)
|
|
7
|
+
from unique_toolkit.agentic.tools.factory import ToolFactory
|
|
8
|
+
|
|
9
|
+
ToolFactory.register_tool(AskUserTool, AskUserToolConfig)
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"AskUserTool",
|
|
13
|
+
"AskUserToolConfig",
|
|
14
|
+
]
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from pydantic import Field
|
|
4
|
+
|
|
5
|
+
from unique_toolkit._common.pydantic.rjsf_tags import RJSFMetaTag
|
|
6
|
+
from unique_toolkit.agentic.tools.schemas import BaseToolConfig
|
|
7
|
+
from unique_toolkit.elicitation import (
|
|
8
|
+
ElicitationCancelledException,
|
|
9
|
+
ElicitationDeclinedException,
|
|
10
|
+
ElicitationExpiredException,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
_DEFAULT_TOOL_DESCRIPTION = """
|
|
14
|
+
Ask the user a question through a structured form and block until they answer. Use whenever you need information, a decision, or confirmation before continuing correctly: clarifying questions, confirmation before destructive or irreversible work, missing parameters, or choosing among plausible options. Do not ask the user in normal chat text while this tool is available—call AskUser, wait for the result, then continue. If unsure which interpretation, scope, or value applies, call AskUser instead of guessing. Destructive actions must include an explicit confirmation field. Form and chat anchoring are handled for you; the call blocks until the user responds, declines, cancels, or times out.
|
|
15
|
+
""".strip()
|
|
16
|
+
|
|
17
|
+
_DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT = """
|
|
18
|
+
- If your next message would ask the user for information, a decision, or confirmation, call AskUser instead of writing the question in chat.
|
|
19
|
+
- If more than one reasonable reading of the request exists, call AskUser before acting—do not silently pick a default.
|
|
20
|
+
- Destructive or irreversible actions require an explicit confirmation field (e.g. boolean `confirm`) in `response_schema`.
|
|
21
|
+
""".strip()
|
|
22
|
+
|
|
23
|
+
_DEFAULT_MESSAGE_DESCRIPTION = "The question or prompt shown to the user"
|
|
24
|
+
|
|
25
|
+
_DEFAULT_RESPONSE_SCHEMA_DESCRIPTION = """
|
|
26
|
+
JSON Schema object (root type "object") for the form shown to the user; you construct it. Single string property for free-text; boolean for a confirmation; string + enum for one choice (dropdown); array with items.enum for choose-many. Mark needed fields required and add short property descriptions (shown as help text). Prefer one small form over many calls.
|
|
27
|
+
Examples:
|
|
28
|
+
- free-text: {"type":"object","properties":{"answer":{"type":"string"}},"required":["answer"]};
|
|
29
|
+
- confirm: {"type":"object","properties":{"confirm":{"type":"boolean"}},"required":["confirm"]};
|
|
30
|
+
- choice: {"type":"object","properties":{"region":{"type":"string","enum":["EU","US"]}},"required":["region"]};
|
|
31
|
+
- multi: {"type":"object","properties":{"topics":{"type":"array","items":{"type":"string","enum":["a","b"]}}}}.
|
|
32
|
+
""".strip()
|
|
33
|
+
|
|
34
|
+
_TIMEOUT_SECONDS_MIN = 1
|
|
35
|
+
_TIMOUT_SECONDS_MAX = 3600
|
|
36
|
+
|
|
37
|
+
_POLLING_SECONDS_MIN = 0.5
|
|
38
|
+
_POLLING_SECONDS_MAX = 60
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class AskUserToolConfig(BaseToolConfig):
|
|
42
|
+
tool_description: Annotated[
|
|
43
|
+
str,
|
|
44
|
+
RJSFMetaTag.StringWidget.textarea(
|
|
45
|
+
rows=len(_DEFAULT_TOOL_DESCRIPTION.splitlines())
|
|
46
|
+
),
|
|
47
|
+
] = Field(
|
|
48
|
+
default=_DEFAULT_TOOL_DESCRIPTION,
|
|
49
|
+
description="Description shown to the model for this tool.",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
tool_description_for_system_prompt: Annotated[
|
|
53
|
+
str,
|
|
54
|
+
RJSFMetaTag.StringWidget.textarea(
|
|
55
|
+
rows=len(_DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT.splitlines())
|
|
56
|
+
),
|
|
57
|
+
] = Field(
|
|
58
|
+
default=_DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT,
|
|
59
|
+
description="Extra system guidance about when and how to use AskUser.",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
message_description: Annotated[
|
|
63
|
+
str,
|
|
64
|
+
RJSFMetaTag.StringWidget.textarea(
|
|
65
|
+
rows=len(_DEFAULT_MESSAGE_DESCRIPTION.splitlines())
|
|
66
|
+
),
|
|
67
|
+
] = Field(
|
|
68
|
+
default=_DEFAULT_MESSAGE_DESCRIPTION,
|
|
69
|
+
description="Description of the `message` parameter shown to the model.",
|
|
70
|
+
title="`message` tool input field description",
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
response_schema_description: Annotated[
|
|
74
|
+
str,
|
|
75
|
+
RJSFMetaTag.StringWidget.textarea(
|
|
76
|
+
rows=len(_DEFAULT_MESSAGE_DESCRIPTION.splitlines())
|
|
77
|
+
),
|
|
78
|
+
] = Field(
|
|
79
|
+
default=_DEFAULT_RESPONSE_SCHEMA_DESCRIPTION,
|
|
80
|
+
description="Description of the `response_schema` parameter shown to the model.",
|
|
81
|
+
title="`response_schema` tool input field description",
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
declined_message: Annotated[
|
|
85
|
+
str,
|
|
86
|
+
RJSFMetaTag.StringWidget.textarea(
|
|
87
|
+
rows=len(ElicitationDeclinedException.INSTRUCTION.splitlines())
|
|
88
|
+
),
|
|
89
|
+
] = Field(
|
|
90
|
+
default=ElicitationDeclinedException.INSTRUCTION,
|
|
91
|
+
description="Message returned to the model when the user declines the request.",
|
|
92
|
+
title="Declined response",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
cancelled_message: Annotated[
|
|
96
|
+
str,
|
|
97
|
+
RJSFMetaTag.StringWidget.textarea(
|
|
98
|
+
rows=len(ElicitationCancelledException.INSTRUCTION.splitlines())
|
|
99
|
+
),
|
|
100
|
+
] = Field(
|
|
101
|
+
default=ElicitationCancelledException.INSTRUCTION,
|
|
102
|
+
description="Message returned to the model when the user cancels the request.",
|
|
103
|
+
title="Cancelled response",
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
expired_message: Annotated[
|
|
107
|
+
str,
|
|
108
|
+
RJSFMetaTag.StringWidget.textarea(
|
|
109
|
+
rows=len(ElicitationExpiredException.INSTRUCTION.splitlines())
|
|
110
|
+
),
|
|
111
|
+
] = Field(
|
|
112
|
+
default=ElicitationExpiredException.INSTRUCTION,
|
|
113
|
+
description="Message returned to the model when the request expires before the user responds.",
|
|
114
|
+
title="Expired response",
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
timeout_seconds: Annotated[
|
|
118
|
+
int,
|
|
119
|
+
RJSFMetaTag.NumberWidget.updown(
|
|
120
|
+
min=_TIMEOUT_SECONDS_MIN, max=_TIMOUT_SECONDS_MAX
|
|
121
|
+
),
|
|
122
|
+
] = Field(
|
|
123
|
+
default=300,
|
|
124
|
+
ge=_TIMEOUT_SECONDS_MIN,
|
|
125
|
+
le=_TIMOUT_SECONDS_MAX,
|
|
126
|
+
description="Maximum seconds to wait for the user to respond.",
|
|
127
|
+
)
|
|
128
|
+
poll_interval_seconds: Annotated[
|
|
129
|
+
float,
|
|
130
|
+
RJSFMetaTag.NumberWidget.updown(
|
|
131
|
+
min=_POLLING_SECONDS_MIN, max=_POLLING_SECONDS_MAX, step=0.5
|
|
132
|
+
),
|
|
133
|
+
] = Field(
|
|
134
|
+
default=1.0,
|
|
135
|
+
ge=_POLLING_SECONDS_MIN,
|
|
136
|
+
le=_POLLING_SECONDS_MAX,
|
|
137
|
+
description="Seconds to wait between attempts when checking whether user has responded.",
|
|
138
|
+
)
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
import logging
|
|
4
|
+
from typing import Annotated, override
|
|
5
|
+
|
|
6
|
+
from pydantic import BaseModel, Field, JsonValue, StringConstraints
|
|
7
|
+
|
|
8
|
+
from unique_toolkit.agentic.evaluation.schemas import EvaluationMetricName
|
|
9
|
+
from unique_toolkit.agentic.tools.experimental.ask_user_tool.config import (
|
|
10
|
+
AskUserToolConfig,
|
|
11
|
+
)
|
|
12
|
+
from unique_toolkit.agentic.tools.schemas import ToolCallResponse
|
|
13
|
+
from unique_toolkit.agentic.tools.tool import Tool
|
|
14
|
+
from unique_toolkit.agentic.tools.tool_progress_reporter import ToolProgressReporter
|
|
15
|
+
from unique_toolkit.app.schemas import ChatEvent
|
|
16
|
+
from unique_toolkit.elicitation import (
|
|
17
|
+
ElicitationCancelledException,
|
|
18
|
+
ElicitationDeclinedException,
|
|
19
|
+
ElicitationExpiredException,
|
|
20
|
+
ElicitationMode,
|
|
21
|
+
)
|
|
22
|
+
from unique_toolkit.language_model.schemas import (
|
|
23
|
+
LanguageModelFunction,
|
|
24
|
+
LanguageModelToolDescription,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
_LOGGER = logging.getLogger(__name__)
|
|
28
|
+
|
|
29
|
+
MessageType = Annotated[str, StringConstraints(strip_whitespace=True, min_length=1)]
|
|
30
|
+
ResponseSchemaType = dict[str, JsonValue]
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class AskUserToolInput(BaseModel):
|
|
34
|
+
message: MessageType
|
|
35
|
+
response_schema: ResponseSchemaType
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class AskUserTool(Tool[AskUserToolConfig]):
|
|
39
|
+
name = "AskUser"
|
|
40
|
+
DISPLAY_NAME = "Ask User"
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
config: AskUserToolConfig,
|
|
45
|
+
event: ChatEvent,
|
|
46
|
+
tool_progress_reporter: ToolProgressReporter | None = None,
|
|
47
|
+
) -> None:
|
|
48
|
+
super().__init__(
|
|
49
|
+
config=config, event=event, tool_progress_reporter=tool_progress_reporter
|
|
50
|
+
)
|
|
51
|
+
self._lock = asyncio.Lock()
|
|
52
|
+
|
|
53
|
+
@override
|
|
54
|
+
def display_name(self) -> str:
|
|
55
|
+
return self.DISPLAY_NAME
|
|
56
|
+
|
|
57
|
+
@override
|
|
58
|
+
def tool_description(self) -> LanguageModelToolDescription:
|
|
59
|
+
class AskUserToolInputWithDescriptions(AskUserToolInput):
|
|
60
|
+
message: MessageType = Field(description=self.config.message_description)
|
|
61
|
+
response_schema: ResponseSchemaType = Field(
|
|
62
|
+
description=self.config.response_schema_description
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
return LanguageModelToolDescription(
|
|
66
|
+
name=self.name,
|
|
67
|
+
description=self.config.tool_description,
|
|
68
|
+
parameters=AskUserToolInputWithDescriptions,
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
@override
|
|
72
|
+
def tool_description_for_system_prompt(self) -> str:
|
|
73
|
+
return self.config.tool_description_for_system_prompt
|
|
74
|
+
|
|
75
|
+
@override
|
|
76
|
+
def is_capability(self) -> bool:
|
|
77
|
+
return True
|
|
78
|
+
|
|
79
|
+
@override
|
|
80
|
+
def evaluation_check_list(self) -> list[EvaluationMetricName]:
|
|
81
|
+
return []
|
|
82
|
+
|
|
83
|
+
@override
|
|
84
|
+
def get_evaluation_checks_based_on_tool_response(
|
|
85
|
+
self,
|
|
86
|
+
tool_response: ToolCallResponse,
|
|
87
|
+
) -> list[EvaluationMetricName]:
|
|
88
|
+
return []
|
|
89
|
+
|
|
90
|
+
@override
|
|
91
|
+
async def run(self, tool_call: LanguageModelFunction) -> ToolCallResponse:
|
|
92
|
+
# When multiple elicitation calls are created, the frontend will render them one by one
|
|
93
|
+
# We need to lock the execution of the tool so that the timeout starts when the user
|
|
94
|
+
# actually sees the elicitation call
|
|
95
|
+
async with self._lock:
|
|
96
|
+
return await self._run(tool_call)
|
|
97
|
+
|
|
98
|
+
async def _run(self, tool_call: LanguageModelFunction) -> ToolCallResponse:
|
|
99
|
+
params = AskUserToolInput.model_validate(tool_call.arguments)
|
|
100
|
+
|
|
101
|
+
service = self.chat_service.elicitation
|
|
102
|
+
|
|
103
|
+
_LOGGER.info("Creating elicitation request")
|
|
104
|
+
|
|
105
|
+
created = await service.create_async(
|
|
106
|
+
mode=ElicitationMode.FORM,
|
|
107
|
+
message=params.message,
|
|
108
|
+
tool_name=self.display_name(),
|
|
109
|
+
json_schema=params.response_schema,
|
|
110
|
+
expires_in_seconds=self.config.timeout_seconds,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
_LOGGER.info("Elicitation request (id %s) successfully created", created.id)
|
|
114
|
+
|
|
115
|
+
try:
|
|
116
|
+
elicitation = await service.wait_for_response_async(
|
|
117
|
+
elicitation_id=created.id,
|
|
118
|
+
timeout_seconds=self.config.timeout_seconds,
|
|
119
|
+
poll_interval_seconds=self.config.poll_interval_seconds,
|
|
120
|
+
)
|
|
121
|
+
except ElicitationDeclinedException:
|
|
122
|
+
_LOGGER.info("Elicitation with id %s was declined", created.id)
|
|
123
|
+
return ToolCallResponse(
|
|
124
|
+
id=tool_call.id,
|
|
125
|
+
name=self.name,
|
|
126
|
+
content=self.config.declined_message,
|
|
127
|
+
)
|
|
128
|
+
except ElicitationCancelledException:
|
|
129
|
+
_LOGGER.info("Elicitation with id %s was cancelled", created.id)
|
|
130
|
+
return ToolCallResponse(
|
|
131
|
+
id=tool_call.id,
|
|
132
|
+
name=self.name,
|
|
133
|
+
content=self.config.cancelled_message,
|
|
134
|
+
)
|
|
135
|
+
except ElicitationExpiredException:
|
|
136
|
+
_LOGGER.info("Elicitation with id %s has expired", created.id)
|
|
137
|
+
return ToolCallResponse(
|
|
138
|
+
id=tool_call.id,
|
|
139
|
+
name=self.name,
|
|
140
|
+
content=self.config.expired_message,
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
_LOGGER.info("User responded to elicitation request")
|
|
144
|
+
|
|
145
|
+
return ToolCallResponse(
|
|
146
|
+
id=tool_call.id,
|
|
147
|
+
name=self.name,
|
|
148
|
+
content=json.dumps(elicitation.response_content, ensure_ascii=False),
|
|
149
|
+
)
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import asyncio
|
|
1
2
|
from typing import Any
|
|
2
3
|
|
|
3
4
|
from unique_toolkit._common.validate_required_values import validate_required_values
|
|
4
5
|
from unique_toolkit.app.schemas import ChatEvent, Correlation
|
|
6
|
+
from unique_toolkit.elicitation.exceptions import (
|
|
7
|
+
ElicitationCancelledException,
|
|
8
|
+
ElicitationDeclinedException,
|
|
9
|
+
ElicitationExpiredException,
|
|
10
|
+
)
|
|
5
11
|
from unique_toolkit.elicitation.functions import (
|
|
6
12
|
create_elicitation,
|
|
7
13
|
create_elicitation_async,
|
|
@@ -18,6 +24,7 @@ from unique_toolkit.elicitation.schemas import (
|
|
|
18
24
|
ElicitationList,
|
|
19
25
|
ElicitationMode,
|
|
20
26
|
ElicitationResponseResult,
|
|
27
|
+
ElicitationStatus,
|
|
21
28
|
)
|
|
22
29
|
|
|
23
30
|
|
|
@@ -235,6 +242,45 @@ class ElicitationService:
|
|
|
235
242
|
elicitation_id=elicitation_id,
|
|
236
243
|
)
|
|
237
244
|
|
|
245
|
+
async def wait_for_response_async(
|
|
246
|
+
self,
|
|
247
|
+
*,
|
|
248
|
+
elicitation_id: str,
|
|
249
|
+
timeout_seconds: int,
|
|
250
|
+
poll_interval_seconds: float = 1.0,
|
|
251
|
+
) -> Elicitation:
|
|
252
|
+
"""
|
|
253
|
+
Poll an elicitation until the user accepts it.
|
|
254
|
+
|
|
255
|
+
Args:
|
|
256
|
+
elicitation_id (str): The elicitation ID to poll.
|
|
257
|
+
timeout_seconds (int): How long to wait before giving up.
|
|
258
|
+
poll_interval_seconds (float): Seconds between polls.
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
Elicitation: The accepted elicitation.
|
|
262
|
+
|
|
263
|
+
Raises:
|
|
264
|
+
ElicitationDeclinedException: If the user declined.
|
|
265
|
+
ElicitationCancelledException: If the user cancelled.
|
|
266
|
+
ElicitationExpiredException: If the request expired or timed out.
|
|
267
|
+
"""
|
|
268
|
+
num_trials = int(timeout_seconds / poll_interval_seconds) + 1
|
|
269
|
+
for _ in range(num_trials):
|
|
270
|
+
elicitation = await self.get_async(elicitation_id)
|
|
271
|
+
match elicitation.status:
|
|
272
|
+
case ElicitationStatus.ACCEPTED:
|
|
273
|
+
return elicitation
|
|
274
|
+
case ElicitationStatus.DECLINED:
|
|
275
|
+
raise ElicitationDeclinedException()
|
|
276
|
+
case ElicitationStatus.CANCELLED:
|
|
277
|
+
raise ElicitationCancelledException()
|
|
278
|
+
case ElicitationStatus.EXPIRED:
|
|
279
|
+
raise ElicitationExpiredException()
|
|
280
|
+
case _:
|
|
281
|
+
await asyncio.sleep(poll_interval_seconds)
|
|
282
|
+
raise ElicitationExpiredException()
|
|
283
|
+
|
|
238
284
|
# List Pending Methods
|
|
239
285
|
############################################################################
|
|
240
286
|
|
{unique_toolkit-2026.28.0.dev1.dist-info → unique_toolkit-2026.28.0.dev2.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-toolkit
|
|
3
|
-
Version: 2026.28.0.
|
|
3
|
+
Version: 2026.28.0.dev2
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Cedric Klinkert, Martin Fadler, Sadique Sheik, Fabian Schläpfer, Pascal Hauri, Ejiroghene Oki-Peter, Rami Azouz, Ricardo Visini, Sanzio Monti
|
|
6
6
|
Author-email: Cedric Klinkert <cedric.klinkert@unique.ch>, Martin Fadler <martin.fadler@unique.ch>, Sadique Sheik <sadique@unique.ch>, Fabian Schläpfer <fabian@unique.ch>, Pascal Hauri <pascal@unique.ch>, Ejiroghene Oki-Peter <oki-peter.ejiroghene@unique.ai>, Rami Azouz <rami.ext@unique.ch>, Ricardo Visini <ricardo.visini@unique.ch>, Sanzio Monti <sanzio.monti@unique.ai>
|
|
@@ -16,7 +16,7 @@ Requires-Dist: sseclient>=0.0.27,<0.0.28
|
|
|
16
16
|
Requires-Dist: openai>=1.105.0,<3
|
|
17
17
|
Requires-Dist: platformdirs>=4.0.0,<5
|
|
18
18
|
Requires-Dist: pillow>=12.1.1
|
|
19
|
-
Requires-Dist: unique-sdk>=2026.28.0.
|
|
19
|
+
Requires-Dist: unique-sdk>=2026.28.0.dev3,<2026.28.0rc0
|
|
20
20
|
Requires-Dist: jambo>=0.1.2,<0.2
|
|
21
21
|
Requires-Dist: jinja2>=3.1.6,<4
|
|
22
22
|
Requires-Dist: docxtpl>=0.20.1,<0.21
|
|
@@ -175,7 +175,10 @@ unique_toolkit/agentic/tools/a2a/tool/service.py,sha256=mRrDYBEMYgk36xqLwtolRh9r
|
|
|
175
175
|
unique_toolkit/agentic/tools/a2a/tool/test/test_service_utils.py,sha256=x4leRxnGgqD-XyXPkW2z1ekv4Ja7EStXd-24LGadPZA,24858
|
|
176
176
|
unique_toolkit/agentic/tools/agent_chunks_hanlder.py,sha256=eO0g46wZOQlmWqYYVGiszRVe8K2LX-9qW30ZCdGg5eE,1943
|
|
177
177
|
unique_toolkit/agentic/tools/config.py,sha256=LUKSENFvBuOPyllCGEmoO8Q_1HpAw4hZuTxfNmyFHWA,3905
|
|
178
|
-
unique_toolkit/agentic/tools/experimental/__init__.py,sha256=
|
|
178
|
+
unique_toolkit/agentic/tools/experimental/__init__.py,sha256=ArEcXHGPtMRNsDnsyo9v1fev0EZWdJ6D7NWdPEFLQKM,956
|
|
179
|
+
unique_toolkit/agentic/tools/experimental/ask_user_tool/__init__.py,sha256=B8srRVw4vMLa4dZE5yoF1Bqpjlv8moh_m-dP2BVRjDc,375
|
|
180
|
+
unique_toolkit/agentic/tools/experimental/ask_user_tool/config.py,sha256=z95ZaxkMvsmjVaUYWWZrvpD21-Us1KNUrMgXzpF4uo4,5923
|
|
181
|
+
unique_toolkit/agentic/tools/experimental/ask_user_tool/tool.py,sha256=yTjONO1Ieh3YsHJzebNstd73YoK40V6wG9o_8-avk30,5111
|
|
179
182
|
unique_toolkit/agentic/tools/experimental/open_file_tool/__init__.py,sha256=hPkz1tbiup8-QM62QMLWA1PpUmzX5VsNUnXsXw1_dMY,319
|
|
180
183
|
unique_toolkit/agentic/tools/experimental/open_file_tool/config.py,sha256=FQylVpCkOw06PSnfODOBwWARRrAI7UoUELzApWNVb2w,4342
|
|
181
184
|
unique_toolkit/agentic/tools/experimental/open_file_tool/runtime.py,sha256=SOIFV2N8USPGHNBnzId2nJPhZiJ3kGO5AwAiKJBNhdI,14383
|
|
@@ -269,7 +272,7 @@ unique_toolkit/elicitation/constants.py,sha256=ab24uagL6ynOKQrLMUChkFxI7dUyBYCoh
|
|
|
269
272
|
unique_toolkit/elicitation/exceptions.py,sha256=hF17eW4GGrtHw0lo77YfZdyIy65SGaWhxoJPx46GK7c,4082
|
|
270
273
|
unique_toolkit/elicitation/functions.py,sha256=RWIglWH9SpiGunqiU7hO2TXkqASkAfk4CfJ3m4uJewU,11417
|
|
271
274
|
unique_toolkit/elicitation/schemas.py,sha256=ugss-r0r8O9XwGpYAkklnLDLvp1XVyzHS521HU8BOjY,5735
|
|
272
|
-
unique_toolkit/elicitation/service.py,sha256=
|
|
275
|
+
unique_toolkit/elicitation/service.py,sha256=cdJ8XVQhvhb_AkZQyd7IrkZ9ktLKs_TZlglNIpcUD-0,12507
|
|
273
276
|
unique_toolkit/embedding/__init__.py,sha256=uUyzjonPvuDCYsvXCIt7ErQXopLggpzX-MEQd3_e2kE,250
|
|
274
277
|
unique_toolkit/embedding/constants.py,sha256=Lj8-Lcy1FvuC31PM9Exq7vaFuxQV4pEI1huUMFX-J2M,52
|
|
275
278
|
unique_toolkit/embedding/functions.py,sha256=OWzY-iPNBjwXgSNNXDmu89Lzu-PAMG3Q7igtUcFrcc8,1944
|
|
@@ -399,6 +402,6 @@ unique_toolkit/short_term_memory/service.py,sha256=Qo-c9yxzC1ZEEHJyIG_vnRs_ef0SK
|
|
|
399
402
|
unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
400
403
|
unique_toolkit/smart_rules/compile.py,sha256=vRe0aMJWuVIK-VsqomgxQImzke7MDmwgSxxJfYCa7zw,1386
|
|
401
404
|
unique_toolkit/test_utilities/events.py,sha256=FLrhMh0A_mQutAUjoD0FdMcVQ4Gq31r35OVGzRjvLro,6760
|
|
402
|
-
unique_toolkit-2026.28.0.
|
|
403
|
-
unique_toolkit-2026.28.0.
|
|
404
|
-
unique_toolkit-2026.28.0.
|
|
405
|
+
unique_toolkit-2026.28.0.dev2.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
|
|
406
|
+
unique_toolkit-2026.28.0.dev2.dist-info/METADATA,sha256=-L08qC8wJBPOovWUmGDdBRkhEdhxxYe-8LGLw6dW_Rs,7426
|
|
407
|
+
unique_toolkit-2026.28.0.dev2.dist-info/RECORD,,
|
|
File without changes
|