unique_toolkit 2026.28.0.dev7__py3-none-any.whl → 2026.28.0.dev9__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.
@@ -180,6 +180,7 @@ def map_references(references: list[ContentReference]) -> list[dict[str, Any]]:
180
180
  return [
181
181
  {
182
182
  "name": ref.name,
183
+ "description": ref.description,
183
184
  "url": ref.url,
184
185
  "sequenceNumber": ref.sequence_number,
185
186
  "sourceId": ref.source_id,
@@ -199,6 +200,7 @@ def map_references_with_original_index(
199
200
  return [
200
201
  {
201
202
  "name": ref.name,
203
+ "description": ref.description,
202
204
  "url": ref.url,
203
205
  "sequenceNumber": ref.sequence_number,
204
206
  "sourceId": ref.source_id,
@@ -215,6 +215,17 @@ class ContentReference(BaseModel):
215
215
  sequence_number: int
216
216
  source: str
217
217
  source_id: str
218
+ description: str | None = Field(
219
+ default=None,
220
+ description=(
221
+ "Optional free-text/structured description carried alongside the "
222
+ "reference. Used by MCP tool references (UN-22310) to carry an "
223
+ 'enriched ``{"mcp": {connectorName, title, details?, mcpServerId?}}`` '
224
+ "JSON payload the chat frontend renders as a card. Nullable "
225
+ "end-to-end (node-chat persists it as a nullable column; empty "
226
+ "values are dropped before sending)."
227
+ ),
228
+ )
218
229
  url: str | None = Field(
219
230
  default=None,
220
231
  description=(
@@ -241,6 +252,8 @@ class ContentReference(BaseModel):
241
252
  "source": reference["source"],
242
253
  "source_id": reference["sourceId"],
243
254
  }
255
+ if "description" in reference:
256
+ kwargs["description"] = reference["description"]
244
257
  if "originalIndex" in reference:
245
258
  kwargs["original_index"] = reference["originalIndex"]
246
259
 
@@ -2,8 +2,15 @@
2
2
 
3
3
  Single responsibility: owns every ``unique_sdk.Message.modify_async`` call
4
4
  related to a streaming response (``startedStreamingAt``, incremental text
5
- + references, ``stoppedStreamingAt``, ``completedAt``), plus the
6
- ``content_chunks`` used to filter references down to what was actually cited.
5
+ + references, and ``stoppedStreamingAt``), plus the ``content_chunks`` used
6
+ to filter references down to what was actually cited.
7
+
8
+ The same message is streamed into once per agent round, and this subscriber
9
+ only sees per-request boundaries (never end-of-turn). It therefore stamps
10
+ ``stoppedStreamingAt`` only on rounds that produced answer text; tool-call
11
+ rounds (empty text) leave it null so the message stays in the streaming
12
+ state. ``completedAt`` is intentionally **not** written here — the
13
+ orchestrator marks completion at end-of-turn via ``set_completed_at``.
7
14
 
8
15
  Attach by calling :meth:`register` once on the owned bus:
9
16
 
@@ -162,6 +169,10 @@ class MessagePersistingSubscriber:
162
169
  if event.appendices:
163
170
  final_text = final_text + "".join(event.appendices)
164
171
 
172
+ # Only mark streaming stopped on the answer round; tool-call rounds have
173
+ # empty text and must stay "streaming" so the frontend keeps the steps.
174
+ stopped_streaming_at = now_iso if final_text else None
175
+
165
176
  await unique_sdk.Message.modify_async(
166
177
  id=event.message_id,
167
178
  chatId=event.chat_id,
@@ -173,6 +184,5 @@ class MessagePersistingSubscriber:
173
184
  # Chat completions persist their request as a JSON array; the SDK type is narrower.
174
185
  gptRequest=event.gpt_request, # pyright: ignore[reportArgumentType]
175
186
  debugInfo=event.debug_info,
176
- stoppedStreamingAt=cast(Any, now_iso),
177
- completedAt=cast(Any, now_iso),
187
+ stoppedStreamingAt=cast(Any, stopped_streaming_at),
178
188
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-toolkit
3
- Version: 2026.28.0.dev7
3
+ Version: 2026.28.0.dev9
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.dev10,<2026.28.0rc0
19
+ Requires-Dist: unique-sdk>=2026.28.0.dev11,<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
@@ -248,7 +248,7 @@ unique_toolkit/chat/__init__.py,sha256=N9RubtxWN7UF0DlxP7YgeNTgjjk6p7AwkbGaVvuZC
248
248
  unique_toolkit/chat/cancellation.py,sha256=HvGZK-daCMSr0M0AnvMY3EBPH1N_UqQPfrbTjwr8owk,5645
249
249
  unique_toolkit/chat/constants.py,sha256=05kq6zjqUVB2d6_P7s-90nbljpB3ryxwCI-CAz0r2O4,83
250
250
  unique_toolkit/chat/deprecated/service.py,sha256=8_XoopUWHT396Z_5gwMmsI6v4NGVgQirSJCYUW4Gx8c,9339
251
- unique_toolkit/chat/functions.py,sha256=vj0sdeBVm-vsrZOwsHAfCUtpdTwQNgr-aVayvRhUCp4,52360
251
+ unique_toolkit/chat/functions.py,sha256=8PXqo4X2BJhsbHkD9X5Ykqz-iVqbRJ1UlWuCNl1XSX8,52448
252
252
  unique_toolkit/chat/rendering.py,sha256=c8YiV9oADRrJQ5A_QBJ4_UFc0NZ-2vVaa7tupoMusso,880
253
253
  unique_toolkit/chat/responses_api.py,sha256=QtCOe3TI242N1JChhoFikxUCvGY6xfTvSmaE9Ta8HSM,19811
254
254
  unique_toolkit/chat/schemas.py,sha256=l-Epugu27RoajiX5OkFO-BrVNey-wfTmaXiEmNNmG7s,7396
@@ -258,7 +258,7 @@ unique_toolkit/chat/utils.py,sha256=CsD9IER2gA1IOV0fmUOl-N0LmKvA7JP9dGrOqeOY0Gg,
258
258
  unique_toolkit/content/__init__.py,sha256=nnQDfnNTEvI8-3dgWvIojoFDYU7edwd8Kloi6lMDG0M,1586
259
259
  unique_toolkit/content/constants.py,sha256=1iy4Y67xobl5VTnJB6SxSyuoBWbdLl9244xfVMUZi5o,60
260
260
  unique_toolkit/content/functions.py,sha256=avnlEQ1FkVz2NTbXUkafU04jzygqOJtUMQL605rEL4c,34019
261
- unique_toolkit/content/schemas.py,sha256=00qbe-DlUjqlf-n3QVOotZjpsj0LZNnUoPmdwyMjVHY,10667
261
+ unique_toolkit/content/schemas.py,sha256=AmnlqMpA_JgbgsaZF6Xdy8kt9lcY0YCqlfqpG1tYWeE,11306
262
262
  unique_toolkit/content/service.py,sha256=S_sFtG1hJd-zz7XyP-6Gu-B8_Xx-r5v46qZLWdRRyRs,29477
263
263
  unique_toolkit/content/smart_rules.py,sha256=9GlHXm63POTi4jy5hW0qUjeqy-JSeL1wIbURM1GKhc4,11481
264
264
  unique_toolkit/content/utils.py,sha256=keDkqu_ZzQY0y_g7g_XLOza3p4XsvfqVVDI9ylM91KY,10115
@@ -336,7 +336,7 @@ unique_toolkit/experimental/integrations/openai/streaming/event_routing/response
336
336
  unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/text_delta_event_handler.py,sha256=JB-7W89K4pT6K8A9Z_f_Pow5p-EIGwLoLUSb9BI3qW4,3634
337
337
  unique_toolkit/experimental/integrations/openai/streaming/event_routing/responses/tool_call_event_handler.py,sha256=iELT-H3-u6eG3D3X9Qz0QfTlDj-IfHBAq7bWYR7Dd5U,3198
338
338
  unique_toolkit/experimental/integrations/openai/streaming/event_routing/subscribers/__init__.py,sha256=4wpUt9kzfPzncO9tlKcvOQUzQG5e6kVp5AKZI5grxOk,276
339
- unique_toolkit/experimental/integrations/openai/streaming/event_routing/subscribers/message_persister.py,sha256=nHh2vQWF6YWurdkijof6UXhTMFzllj_4eSdr8nm9aDI,8016
339
+ unique_toolkit/experimental/integrations/openai/streaming/event_routing/subscribers/message_persister.py,sha256=cqwDI6PLLiocaBUBL6VPLqgucH_Y_wKTdN3HdadFq6k,8635
340
340
  unique_toolkit/experimental/integrations/openai/streaming/event_routing/subscribers/progress_log_persister.py,sha256=VCYGZY3WSpI7mvVs2gO89-M0JenakW01BGfBfFkPDrw,3499
341
341
  unique_toolkit/experimental/resources/__init__.py,sha256=KdMPaaneY0twZ-JBfwImRjXZaWT68NVuOIeqdNXFh_Y,3377
342
342
  unique_toolkit/experimental/resources/content_folder/__init__.py,sha256=c5MUj1xIP10L7tcM4-hG2m1_yUMVfKr_jHAncUXVNvo,2492
@@ -406,6 +406,6 @@ unique_toolkit/short_term_memory/service.py,sha256=2JMBEBn6GoyK-a0xvdcWpPft-3C74
406
406
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
407
407
  unique_toolkit/smart_rules/compile.py,sha256=vRe0aMJWuVIK-VsqomgxQImzke7MDmwgSxxJfYCa7zw,1386
408
408
  unique_toolkit/test_utilities/events.py,sha256=FLrhMh0A_mQutAUjoD0FdMcVQ4Gq31r35OVGzRjvLro,6760
409
- unique_toolkit-2026.28.0.dev7.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
410
- unique_toolkit-2026.28.0.dev7.dist-info/METADATA,sha256=nHNAallyeC9qG-si_8OUQL1asr0rDHCppjABATDQfbU,7427
411
- unique_toolkit-2026.28.0.dev7.dist-info/RECORD,,
409
+ unique_toolkit-2026.28.0.dev9.dist-info/WHEEL,sha256=eh7sammvW2TypMMMGKgsM83HyA_3qQ5Lgg3ynoecH3M,79
410
+ unique_toolkit-2026.28.0.dev9.dist-info/METADATA,sha256=qXosj8SbRg2-BNbpviYvDe9xj98kVKyr0_KLcJFvYvs,7427
411
+ unique_toolkit-2026.28.0.dev9.dist-info/RECORD,,