unique-sdk 2026.32.0.dev5__tar.gz → 2026.32.0.dev7__tar.gz
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_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/PKG-INFO +1 -1
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/pyproject.toml +1 -1
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_api_requestor.py +8 -8
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_util.py +98 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/cli.py +2 -1
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/shell.py +4 -7
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-elicitation/SKILL.md +13 -14
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/README.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/__init__.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_api_resource.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_api_version.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_error.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_http_client.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_list_object.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_object_classes.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_request_options.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_unique_object.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_unique_ql.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_unique_response.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_version.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/_webhook.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/__init__.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_acronyms.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_agentic_table.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_analytics_order.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_benchmarking.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_briefing.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_chat_completion.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_content.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_dynamic_frontend.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_elicitation.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_embedding.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_event.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_folder.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_group.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_integrated.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_llm_models.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_mcp.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message_assessment.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message_execution.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message_log.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message_tool.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_module.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_scheduled_task.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_search.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_search_string.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_short_term_memory.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_space.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_user.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_web_search.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/__init__.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/__main__.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/__init__.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/_citation_manifest.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/agentic_table.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/browser.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/cite_file.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/dynamic_frontend.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/elicitation.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/files.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/folders.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/mcp.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/navigation.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/read.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/scheduled_tasks.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/search.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/subagent.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/web_search.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/web_search_config.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/config.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/formatting.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/identity.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/metadata_filter.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-agentic-table/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-dynamic-frontend/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-file-management/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-mcp/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-scheduled-tasks/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-search/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-subagent/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-uploaded-search/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/skills/unique-cli-web-search/SKILL.md +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/state.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/analytics_order_run.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/benchmarking_run.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/chat_history.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/chat_in_space.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/file_io.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/sources.py +0 -0
- {unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/token.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-sdk
|
|
3
|
-
Version: 2026.32.0.
|
|
3
|
+
Version: 2026.32.0.dev7
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Martin Fadler, Konstantin Krauss, Andreas Hauri
|
|
6
6
|
Author-email: Martin Fadler <martin.fadler@unique.ch>, Konstantin Krauss <konstantin@unique.ch>, Andreas Hauri <andreas@unique.ch>
|
|
@@ -194,8 +194,7 @@ class APIRequestor(object):
|
|
|
194
194
|
)
|
|
195
195
|
|
|
196
196
|
_util.log_info("Request to Unique", method=method, path=abs_url)
|
|
197
|
-
_util.
|
|
198
|
-
"Request details",
|
|
197
|
+
_util.log_request_details(
|
|
199
198
|
data=post_data,
|
|
200
199
|
headers=headers,
|
|
201
200
|
api_version=self.api_version,
|
|
@@ -206,7 +205,7 @@ class APIRequestor(object):
|
|
|
206
205
|
)
|
|
207
206
|
|
|
208
207
|
_util.log_info("Unique response", path=abs_url, status=rcode)
|
|
209
|
-
_util.
|
|
208
|
+
_util.log_response_body(body=rcontent)
|
|
210
209
|
|
|
211
210
|
if "Request-Id" in rheaders:
|
|
212
211
|
request_id = rheaders["Request-Id"]
|
|
@@ -230,11 +229,11 @@ class APIRequestor(object):
|
|
|
230
229
|
)
|
|
231
230
|
|
|
232
231
|
_util.log_info("Async request to Unique", method=method, path=abs_url)
|
|
233
|
-
_util.
|
|
234
|
-
"Async request details",
|
|
232
|
+
_util.log_request_details(
|
|
235
233
|
data=post_data,
|
|
236
234
|
headers=headers,
|
|
237
235
|
api_version=self.api_version,
|
|
236
|
+
message="Async request details",
|
|
238
237
|
)
|
|
239
238
|
|
|
240
239
|
rcontent, rcode, rheaders = await self._client.request_async(
|
|
@@ -242,7 +241,7 @@ class APIRequestor(object):
|
|
|
242
241
|
)
|
|
243
242
|
|
|
244
243
|
_util.log_info("Unique response", path=abs_url, status=rcode)
|
|
245
|
-
_util.
|
|
244
|
+
_util.log_response_body(body=rcontent)
|
|
246
245
|
|
|
247
246
|
if "Request-Id" in rheaders:
|
|
248
247
|
request_id = rheaders["Request-Id"]
|
|
@@ -364,7 +363,8 @@ class APIRequestor(object):
|
|
|
364
363
|
except Exception as e:
|
|
365
364
|
raise _error.APIError(
|
|
366
365
|
"Invalid response body from API: %s "
|
|
367
|
-
"(HTTP response code was %d)"
|
|
366
|
+
"(HTTP response code was %d)"
|
|
367
|
+
% (_util.redacted_body_for_error_message(rbody), rcode),
|
|
368
368
|
cast(bytes, rbody),
|
|
369
369
|
rcode,
|
|
370
370
|
rheaders,
|
|
@@ -399,7 +399,7 @@ class APIRequestor(object):
|
|
|
399
399
|
error_code=status,
|
|
400
400
|
error_type=error_data.get("type"),
|
|
401
401
|
error_message=error_data.get("message"),
|
|
402
|
-
error_params=error_data.get("params"),
|
|
402
|
+
error_params=_util.redacted_error_params(error_data.get("params")),
|
|
403
403
|
)
|
|
404
404
|
|
|
405
405
|
error = cause.get("error", {}) if cause else {}
|
|
@@ -9,6 +9,7 @@ import random
|
|
|
9
9
|
import re
|
|
10
10
|
import sys
|
|
11
11
|
import time
|
|
12
|
+
from collections.abc import Mapping
|
|
12
13
|
from functools import wraps
|
|
13
14
|
from typing import (
|
|
14
15
|
Any,
|
|
@@ -33,6 +34,8 @@ UNIQUE_LOG = os.environ.get("UNIQUE_LOG")
|
|
|
33
34
|
|
|
34
35
|
logger: logging.Logger = logging.getLogger("unique")
|
|
35
36
|
|
|
37
|
+
_REDACTED = "<redacted>"
|
|
38
|
+
|
|
36
39
|
|
|
37
40
|
def _console_log_level():
|
|
38
41
|
if unique_sdk.log in ["debug", "info"]:
|
|
@@ -42,6 +45,42 @@ def _console_log_level():
|
|
|
42
45
|
return None
|
|
43
46
|
|
|
44
47
|
|
|
48
|
+
def _insecure_log_payloads_enabled() -> bool:
|
|
49
|
+
return os.environ.get("INSECURE_UNIQUE_SDK_LOG_PAYLOADS") == "true"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _payload_byte_size(value: Any) -> int:
|
|
53
|
+
if value is None:
|
|
54
|
+
return 0
|
|
55
|
+
if isinstance(value, (bytes, bytearray)):
|
|
56
|
+
return len(value)
|
|
57
|
+
if isinstance(value, str):
|
|
58
|
+
return len(value.encode("utf-8"))
|
|
59
|
+
return len(str(value).encode("utf-8"))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _headers_for_log(headers: Mapping[str, str] | None) -> dict[str, str] | str | None:
|
|
63
|
+
"""Return headers for debug logs; Authorization is always redacted."""
|
|
64
|
+
if not _insecure_log_payloads_enabled():
|
|
65
|
+
return _REDACTED
|
|
66
|
+
if headers is None:
|
|
67
|
+
return None
|
|
68
|
+
try:
|
|
69
|
+
sanitized = dict(headers)
|
|
70
|
+
except (TypeError, ValueError):
|
|
71
|
+
return _REDACTED
|
|
72
|
+
for key in list(sanitized):
|
|
73
|
+
if str(key).lower() == "authorization":
|
|
74
|
+
sanitized[key] = _REDACTED
|
|
75
|
+
return sanitized
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _body_for_log(body: Any) -> Any:
|
|
79
|
+
if _insecure_log_payloads_enabled():
|
|
80
|
+
return body
|
|
81
|
+
return _REDACTED
|
|
82
|
+
|
|
83
|
+
|
|
45
84
|
def log_debug(message, **params):
|
|
46
85
|
msg = logfmt(dict(message=message, **params))
|
|
47
86
|
if _console_log_level() == "debug":
|
|
@@ -56,6 +95,65 @@ def log_info(message, **params):
|
|
|
56
95
|
logger.info(msg)
|
|
57
96
|
|
|
58
97
|
|
|
98
|
+
def log_request_details(
|
|
99
|
+
*,
|
|
100
|
+
data: Any,
|
|
101
|
+
headers: Mapping[str, str] | None,
|
|
102
|
+
api_version: str | None,
|
|
103
|
+
message: str = "Request details",
|
|
104
|
+
) -> None:
|
|
105
|
+
if _insecure_log_payloads_enabled():
|
|
106
|
+
log_debug(
|
|
107
|
+
message,
|
|
108
|
+
data=data,
|
|
109
|
+
headers=_headers_for_log(headers),
|
|
110
|
+
api_version=api_version,
|
|
111
|
+
)
|
|
112
|
+
return
|
|
113
|
+
log_debug(
|
|
114
|
+
message,
|
|
115
|
+
data=_REDACTED,
|
|
116
|
+
headers=_REDACTED,
|
|
117
|
+
api_version=api_version,
|
|
118
|
+
payload_bytes=_payload_byte_size(data),
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def log_response_body(*, body: Any) -> None:
|
|
123
|
+
if _insecure_log_payloads_enabled():
|
|
124
|
+
log_debug("Unique response body", body=body)
|
|
125
|
+
return
|
|
126
|
+
log_debug(
|
|
127
|
+
"Unique response body",
|
|
128
|
+
body=_body_for_log(body),
|
|
129
|
+
payload_bytes=_payload_byte_size(body),
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def redacted_body_for_error_message(body: Any) -> Any:
|
|
134
|
+
"""Body representation safe to embed in exception *messages*.
|
|
135
|
+
|
|
136
|
+
Exception messages surface at ERROR (retry logs, tracebacks) regardless
|
|
137
|
+
of LOG_LEVEL, so the raw body must not be embedded unless the insecure
|
|
138
|
+
opt-in is set. The full body stays available programmatically on the
|
|
139
|
+
exception's ``http_body`` attribute.
|
|
140
|
+
"""
|
|
141
|
+
if _insecure_log_payloads_enabled():
|
|
142
|
+
return body
|
|
143
|
+
return f"<redacted {_payload_byte_size(body)} bytes>"
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def redacted_error_params(params: Any) -> Any:
|
|
147
|
+
"""Error ``params`` for the INFO-level 'Unique error received' log.
|
|
148
|
+
|
|
149
|
+
API validation errors commonly echo submitted values in ``params``, so
|
|
150
|
+
they are redacted unless the insecure opt-in is set.
|
|
151
|
+
"""
|
|
152
|
+
if params is None or _insecure_log_payloads_enabled():
|
|
153
|
+
return params
|
|
154
|
+
return _REDACTED
|
|
155
|
+
|
|
156
|
+
|
|
59
157
|
def logfmt(props):
|
|
60
158
|
def fmt(key, val):
|
|
61
159
|
# Handle case where val is a bytes or bytesarray
|
|
@@ -1373,7 +1373,8 @@ def elicit_ask(
|
|
|
1373
1373
|
@click.option(
|
|
1374
1374
|
"--mode",
|
|
1375
1375
|
type=click.Choice(["FORM", "URL"], case_sensitive=False),
|
|
1376
|
-
|
|
1376
|
+
default="FORM",
|
|
1377
|
+
show_default=True,
|
|
1377
1378
|
help="Elicitation display mode.",
|
|
1378
1379
|
)
|
|
1379
1380
|
@click.option(
|
|
@@ -97,7 +97,7 @@ OVERVIEW_HELP = textwrap.dedent("""\
|
|
|
97
97
|
--placeholder-text <text> Text on the placeholder thinking step
|
|
98
98
|
--cleanup collapse|delete How to tear down the placeholder
|
|
99
99
|
elicit create <message> [opts] Fire-and-forget create
|
|
100
|
-
--mode FORM|URL Display mode (
|
|
100
|
+
--mode FORM|URL Display mode (default: FORM)
|
|
101
101
|
--tool-name / -t <name> Tool label (required)
|
|
102
102
|
--schema <json> JSON schema (FORM mode)
|
|
103
103
|
--url <url> External URL (URL mode)
|
|
@@ -811,7 +811,7 @@ class UniqueShell(cmd.Cmd):
|
|
|
811
811
|
--tool-name / -t <name> Tool label shown in the UI
|
|
812
812
|
--schema <json> JSON schema for form fields
|
|
813
813
|
--url <url> External URL (create with --mode URL)
|
|
814
|
-
--mode FORM|URL Display mode (create only,
|
|
814
|
+
--mode FORM|URL Display mode (create only, default: FORM)
|
|
815
815
|
--chat-id / -c <id> Associated chat ID
|
|
816
816
|
--message-id / -m <id> Associated message ID
|
|
817
817
|
--expires-in <seconds> Auto-expire the request (create only)
|
|
@@ -1033,18 +1033,15 @@ class UniqueShell(cmd.Cmd):
|
|
|
1033
1033
|
message = opts["message"]
|
|
1034
1034
|
if not message:
|
|
1035
1035
|
self._print(
|
|
1036
|
-
"Usage: elicit create <message> --mode FORM|URL --tool-name <name> [options]"
|
|
1036
|
+
"Usage: elicit create <message> [--mode FORM|URL] --tool-name <name> [options]"
|
|
1037
1037
|
)
|
|
1038
1038
|
return
|
|
1039
|
-
if not opts["mode"]:
|
|
1040
|
-
self._print("Error: --mode is required (FORM or URL).")
|
|
1041
|
-
return
|
|
1042
1039
|
if not opts["tool_name"]:
|
|
1043
1040
|
self._print("Error: --tool-name / -t is required.")
|
|
1044
1041
|
return
|
|
1045
1042
|
|
|
1046
1043
|
create_kwargs: dict[str, Any] = {
|
|
1047
|
-
"mode": opts["mode"],
|
|
1044
|
+
"mode": opts["mode"] or "FORM",
|
|
1048
1045
|
"message": message,
|
|
1049
1046
|
"tool_name": opts["tool_name"],
|
|
1050
1047
|
"schema": opts["schema"],
|
|
@@ -161,22 +161,19 @@ unique-cli elicit ask "Which report format do you want?" \
|
|
|
161
161
|
|
|
162
162
|
Always use this before `rm`, `rmdir -r`, mass uploads, or anything irreversible.
|
|
163
163
|
|
|
164
|
+
Use an **empty-properties schema** — the UI's Confirm/Cancel buttons ARE the
|
|
165
|
+
consent. Do **not** add a boolean `confirm` field: the button and the checkbox
|
|
166
|
+
are two separate signals, and a user who presses Confirm with the box unchecked
|
|
167
|
+
would show as **Accepted** in the UI while you would read `confirm: false` and
|
|
168
|
+
wrongly treat it as declined.
|
|
169
|
+
|
|
164
170
|
```bash
|
|
165
|
-
unique-cli elicit ask "
|
|
171
|
+
unique-cli elicit ask "Permanently delete /Archive/2024 and everything inside it? Confirming deletes it immediately — this cannot be undone." \
|
|
166
172
|
--chat-id "$UNIQUE_CHAT_ID" \
|
|
167
|
-
--schema '{
|
|
168
|
-
"type": "object",
|
|
169
|
-
"properties": {
|
|
170
|
-
"confirm": {
|
|
171
|
-
"type": "boolean",
|
|
172
|
-
"description": "Tick to permanently delete"
|
|
173
|
-
}
|
|
174
|
-
},
|
|
175
|
-
"required": ["confirm"]
|
|
176
|
-
}'
|
|
173
|
+
--schema '{"type": "object", "properties": {}}'
|
|
177
174
|
```
|
|
178
175
|
|
|
179
|
-
Proceed **only** if the
|
|
176
|
+
Proceed **only** if the `Status:` is `ACCEPTED`. Treat `DECLINED`, `CANCELLED`, or `EXPIRED` all as "do not proceed" -- tell the user you stopped and return control. Put everything the user needs to decide into the message text, since the form has no fields.
|
|
180
177
|
|
|
181
178
|
### Structured form (multiple fields)
|
|
182
179
|
|
|
@@ -201,7 +198,9 @@ The table below documents `elicit ask`'s flags. `elicit create` takes the
|
|
|
201
198
|
same `--chat-id`, `--message-id`, `--tool-name`, `--schema`, `--metadata`,
|
|
202
199
|
and `--assistant-id` flags, but uses `--expires-in <seconds>` instead of
|
|
203
200
|
`--timeout`/`--poll-interval` (those two apply only to `elicit wait`, which
|
|
204
|
-
you call separately in the polling pattern).
|
|
201
|
+
you call separately in the polling pattern). `elicit create` also takes
|
|
202
|
+
`--mode FORM|URL` (default: `FORM` — you only need to pass it for URL
|
|
203
|
+
elicitations).
|
|
205
204
|
|
|
206
205
|
| Option | Short | Default | Description |
|
|
207
206
|
|--------|-------|---------|-------------|
|
|
@@ -296,7 +295,7 @@ esac
|
|
|
296
295
|
|
|
297
296
|
- Always set `"required"` for fields you actually need -- this guarantees the user cannot submit an empty form.
|
|
298
297
|
- Use `enum` for closed choices so the UI can render a selector.
|
|
299
|
-
-
|
|
298
|
+
- For pure yes/no confirmations use an **empty-properties schema** (`{"type": "object", "properties": {}}`) and gate on `Status: ACCEPTED` — never add a boolean `confirm` field (the Confirm button and the checkbox are two separate signals that can disagree). Reserve `"type": "boolean"` for genuine data fields where `false` is a valid answer the user can still submit with Confirm (e.g. `include_appendix`).
|
|
300
299
|
- Add short `description` strings -- they are shown as help text next to each field.
|
|
301
300
|
- Keep schemas small. Ask at most 5 questions in a single elicitation; if you need more, split the flow so the user is not confused by an oversized form.
|
|
302
301
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/__init__.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_acronyms.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_agentic_table.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_analytics_order.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_benchmarking.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_briefing.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_chat_completion.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_content.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_elicitation.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_embedding.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_integrated.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_llm_models.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message_log.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_message_tool.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_scheduled_task.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_search_string.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/api_resources/_web_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/agentic_table.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/cite_file.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/dynamic_frontend.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/elicitation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/navigation.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/scheduled_tasks.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/web_search.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/cli/commands/web_search_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/analytics_order_run.py
RENAMED
|
File without changes
|
{unique_sdk-2026.32.0.dev5 → unique_sdk-2026.32.0.dev7}/unique_sdk/utils/benchmarking_run.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|