unique_sdk 0.10.17__py3-none-any.whl → 0.10.19__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.
@@ -12,7 +12,6 @@ from typing import (
12
12
 
13
13
  from typing_extensions import NotRequired, Unpack
14
14
 
15
- import unique_sdk
16
15
  from unique_sdk._api_resource import APIResource
17
16
  from unique_sdk._request_options import RequestOptions
18
17
 
@@ -130,9 +129,7 @@ class Content(APIResource["Content"]):
130
129
 
131
130
  class UpdateParams(RequestOptions):
132
131
  contentId: str | None = None
133
- filePath: str | None = None
134
132
  ownerId: str | None = None
135
- parentFolderPath: str | None = None
136
133
  title: str | None = None
137
134
 
138
135
  class Chunk(TypedDict):
@@ -168,7 +165,6 @@ class Content(APIResource["Content"]):
168
165
 
169
166
  class DeleteParams(RequestOptions):
170
167
  contentId: NotRequired[str]
171
- filePath: NotRequired[str]
172
168
  chatId: NotRequired[str]
173
169
 
174
170
  class DeleteResponse(TypedDict):
@@ -406,28 +402,11 @@ class Content(APIResource["Content"]):
406
402
  company_id: str,
407
403
  **params: Unpack["Content.UpdateParams"],
408
404
  ) -> "Content.ContentInfo":
409
- content_id = cls.resolve_content_id_from_file_path(
410
- user_id,
411
- company_id,
412
- params.get("contentId"),
413
- params.get("filePath"),
414
- )
415
- owner_id = unique_sdk.Folder.resolve_scope_id_from_folder_path(
416
- user_id,
417
- company_id,
418
- params.get("ownerId"),
419
- params.get("parentFolderPath"),
420
- )
421
- params.pop("contentId", None)
422
- params.pop("filePath", None)
423
- params.pop("parentFolderPath", None)
424
- params["ownerId"] = owner_id
425
-
426
405
  return cast(
427
406
  "Content.ContentInfo",
428
407
  cls._static_request(
429
408
  "patch",
430
- f"/content/{content_id}",
409
+ f"/content/{params.get('contentId')}",
431
410
  user_id,
432
411
  company_id,
433
412
  params=params,
@@ -441,28 +420,11 @@ class Content(APIResource["Content"]):
441
420
  company_id: str,
442
421
  **params: Unpack["Content.UpdateParams"],
443
422
  ) -> "Content.ContentInfo":
444
- content_id = cls.resolve_content_id_from_file_path(
445
- user_id,
446
- company_id,
447
- params.get("contentId"),
448
- params.get("filePath"),
449
- )
450
- owner_id = unique_sdk.Folder.resolve_scope_id_from_folder_path(
451
- user_id,
452
- company_id,
453
- params.get("ownerId"),
454
- params.get("parentFolderPath"),
455
- )
456
- params.pop("contentId", None)
457
- params.pop("filePath", None)
458
- params.pop("parentFolderPath", None)
459
- params["ownerId"] = owner_id
460
-
461
423
  return cast(
462
424
  "Content.ContentInfo",
463
425
  await cls._static_request_async(
464
426
  "patch",
465
- f"/content/{content_id}",
427
+ f"/content/{params.get('contentId')}",
466
428
  user_id,
467
429
  company_id,
468
430
  params=params,
@@ -479,20 +441,12 @@ class Content(APIResource["Content"]):
479
441
  """
480
442
  Deletes a content by its id or file path.
481
443
  """
482
- content_id = cls.resolve_content_id_from_file_path(
483
- user_id,
484
- company_id,
485
- params.get("contentId"),
486
- params.get("filePath"),
487
- )
488
- params.pop("contentId", None)
489
- params.pop("filePath", None)
490
444
 
491
445
  return cast(
492
446
  "Content.DeleteResponse",
493
447
  cls._static_request(
494
448
  "delete",
495
- f"/content/{content_id}",
449
+ f"/content/{params.get('contentId')}",
496
450
  user_id,
497
451
  company_id,
498
452
  params=params,
@@ -509,20 +463,12 @@ class Content(APIResource["Content"]):
509
463
  """
510
464
  Async deletes a content by its id or file path.
511
465
  """
512
- content_id = cls.resolve_content_id_from_file_path(
513
- user_id,
514
- company_id,
515
- params.get("contentId"),
516
- params.get("filePath"),
517
- )
518
- params.pop("contentId", None)
519
- params.pop("filePath", None)
520
466
 
521
467
  return cast(
522
468
  "Content.DeleteResponse",
523
469
  await cls._static_request_async(
524
470
  "delete",
525
- f"/content/{content_id}",
471
+ f"/content/{params.get('contentId')}",
526
472
  user_id,
527
473
  company_id,
528
474
  params=params,
@@ -1,7 +1,8 @@
1
1
  import asyncio
2
- from typing import List
2
+ from typing import List, Literal
3
3
 
4
4
  from unique_sdk.api_resources._content import Content
5
+ from unique_sdk.api_resources._message import Message
5
6
  from unique_sdk.api_resources._space import Space
6
7
  from unique_sdk.utils.file_io import upload_file
7
8
 
@@ -16,6 +17,7 @@ async def send_message_and_wait_for_completion(
16
17
  chat_id: str = None,
17
18
  poll_interval: float = 1.0,
18
19
  max_wait: float = 60.0,
20
+ stop_condition: Literal["stoppedStreamingAt", "completedAt"] = "stoppedStreamingAt",
19
21
  ) -> "Space.Message":
20
22
  """
21
23
  Sends a prompt asynchronously and polls for completion. (until stoppedStreamingAt is not None)
@@ -27,6 +29,7 @@ async def send_message_and_wait_for_completion(
27
29
  text: The prompt text.
28
30
  poll_interval: Seconds between polls.
29
31
  max_wait: Maximum seconds to wait for completion.
32
+ stop_condition: Defines when to expect a response back, when the assistant stop streaming or when it completes the message. (default: "stoppedStreamingAt")
30
33
  **kwargs: Additional parameters for the prompt.
31
34
 
32
35
  Returns:
@@ -42,11 +45,21 @@ async def send_message_and_wait_for_completion(
42
45
  scopeRules=scope_rules,
43
46
  )
44
47
  chat_id = response.get("chatId")
48
+ message_id = response.get("id")
45
49
 
46
50
  max_attempts = int(max_wait // poll_interval)
47
51
  for _ in range(max_attempts):
48
52
  answer = Space.get_latest_message(user_id, company_id, chat_id)
49
- if answer.get("stoppedStreamingAt") is not None:
53
+ if answer.get(stop_condition) is not None:
54
+ try:
55
+ user_message = Message.retrieve(
56
+ user_id, company_id, message_id, chatId=chat_id
57
+ )
58
+ debug_info = user_message.get("debugInfo")
59
+ answer["debugInfo"] = debug_info
60
+ except Exception as e:
61
+ print(f"Failed to load debug info from user message: {e}")
62
+
50
63
  return answer
51
64
  await asyncio.sleep(poll_interval)
52
65
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_sdk
3
- Version: 0.10.17
3
+ Version: 0.10.19
4
4
  Summary:
5
5
  License: MIT
6
6
  Author: Martin Fadler
@@ -556,32 +556,19 @@ Allows you to ingest a magic table sheet, each row is processed and converted in
556
556
 
557
557
  #### `unique_sdk.Content.update` (Compatible with release >.36)
558
558
 
559
- Allows you to update a file specified by its `contentId` or by its `filePath`.
559
+ Allows you to update a file specified by its `contentId`.
560
560
 
561
- - `contentId` optional if `filePath` is provided, the id of the file to be updated
562
- - `filePath` optional if `contentId` is provided, the absolute path of the file to be updated
561
+ - `contentId` the id of the file to be updated
563
562
 
564
563
  Currently, the following updates are supported:
565
564
 
566
565
  Title update:
567
566
  - `title` optional, allows updating the title of the folder
568
567
 
569
- Move the file to a different folder. this can be done by specifying either the `ownerId` or the `parentFolderPath`.
568
+ Move the file to a different folder. this can be done by specifying either the `ownerId`.
570
569
  - `ownerId` optional, allows moving the file to a different folder. Represents the new folder for the file and it should be the id of a folder e.g.: `scope_dhjfieurfloakmdle`.
571
- - `parentFolderPath` optional, allows moving the file to a different folder. Represents the path new folder for the file.
572
570
 
573
571
 
574
- Example of updating the title of a file specified by its path.
575
-
576
- ```python
577
- unique_sdk.Content.update(
578
- user_id=user_id,
579
- company_id=company_id,
580
- filePath="/Company/finance/january.xls",
581
- title="Revision Deck"
582
- )
583
- ```
584
-
585
572
  Example of moving a file specified by its content id.
586
573
 
587
574
  ```python
@@ -605,25 +592,12 @@ unique_sdk.Content.update(
605
592
  )
606
593
  ```
607
594
 
608
- Example of moving a file to a folder specified by its path.
609
-
610
- ```python
611
- unique_sdk.Content.update(
612
- user_id=user_id,
613
- company_id=company_id,
614
- contentId="cont_ok2343q5owbce80w78hudawu5",
615
- ownerId="scope_e68yz5asho7glfh7c7d041el",
616
- parentFolderPath="/Company/Revisions"
617
- )
618
- ```
619
-
620
595
  #### `unique_sdk.Content.delete` (Compatible with release >.36)
621
596
 
622
- Allows you to delete a file by its `contentId` or by its `filePath`. When deleting by `id`, if the file is part of a chat, the `chatId` also needs do be set. If both `contentId` and `filePath` are provided, `filePath` is ignored.
597
+ Allows you to delete a file by its `contentId`. If the file is part of a chat, the `chatId` also needs do be set.
623
598
 
624
- - `contentId` optional if `filePath` is provided, the id of the file to be deleted
599
+ - `contentId` the id of the file to be deleted
625
600
  - `chatId` optional, the id of the chat where the file is. Only needed if the file is part of a chat
626
- - `filePath` optional if `contentId` is provided, the absolute path of the file to be deleted
627
601
 
628
602
  Example of deleting a file from a chat.
629
603
 
@@ -636,16 +610,6 @@ unique_sdk.Content.delete(
636
610
  )
637
611
  ```
638
612
 
639
- Example of deleting a file by its path.
640
-
641
- ```python
642
- unique_sdk.Content.delete(
643
- user_id=user_id,
644
- company_id=company_id,
645
- filePath="/Company/finance/january.xls",
646
- )
647
- ```
648
-
649
613
  ### Message
650
614
 
651
615
  #### `unique_sdk.Message.list`
@@ -1502,11 +1466,13 @@ The script sends a prompt asynchronously and continuously polls for completion,
1502
1466
  - `chat_id`: The ID of the chat where the message should be sent. If omitted, a new chat will be created.
1503
1467
  - `poll_interval`: The number of seconds to wait between polling attempts (default: `1` second).
1504
1468
  - `max_wait`: The maximum number of seconds to wait for the message to complete (default: `60` seconds).
1469
+ - `stop_condition`: Defines when to expect a response back, when the assistant stop streaming or when it completes the message. (default: "stoppedStreamingAt")
1505
1470
 
1506
1471
  The script ensures you can flexibly interact with spaces in new or ongoing chats, with fine-grained control over tools, context, and polling behavior.
1507
1472
 
1508
1473
  ```python
1509
- latest_message = await unique_sdk.utils.chat_in_space.send_message_and_wait_for_completion(
1474
+ from unique_sdk.utils.chat_in_space import send_message_and_wait_for_completion
1475
+ latest_message = await send_message_and_wait_for_completion(
1510
1476
  user_id=user_id,
1511
1477
  company_id=company_id,
1512
1478
  assistant_id=assistant_id,
@@ -1533,6 +1499,7 @@ latest_message = await unique_sdk.utils.chat_in_space.send_message_and_wait_for_
1533
1499
  }
1534
1500
  ]
1535
1501
  },
1502
+ stop_condition = "completedAt" # If not specified, stoppedStreamingAt will be set by default
1536
1503
  )
1537
1504
  ```
1538
1505
 
@@ -1608,6 +1575,14 @@ All notable changes to this project will be documented in this file.
1608
1575
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
1609
1576
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1610
1577
 
1578
+ ## [0.10.19] - 2025-09-02
1579
+ - Improve `send_message_and_wait_for_completion`:
1580
+ - Add option to select stop_condition `["stoppedStreamingAt", "completedAt"]`.
1581
+ - Load `debugInfo` from `last_user_message` for better developer experience.
1582
+
1583
+ ## [0.10.18] - 2025-09-02
1584
+ - Temporarily remove support for update and delete files by filePath.
1585
+
1611
1586
  ## [0.10.17] - 2025-09-01
1612
1587
  - Add function to update a file
1613
1588
 
@@ -17,7 +17,7 @@ unique_sdk/api_resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
17
17
  unique_sdk/api_resources/_acronyms.py,sha256=GIU1XH1flGWQYcpsFqTYwg4ioIGxVmb15tux84nmhEg,891
18
18
  unique_sdk/api_resources/_agentic_table.py,sha256=8-_f7t-m_iiiOj2835iESoxz91YRxl4-tkxpzQbgdcI,9958
19
19
  unique_sdk/api_resources/_chat_completion.py,sha256=ILCAffxkbkfh2iV9L4KKnfe80gZmT9pWfkNmf3mq68U,2172
20
- unique_sdk/api_resources/_content.py,sha256=rjpTnDXJFw1EGP2n57WLlO_7fO6z8ykrnySkGXpYUEs,15820
20
+ unique_sdk/api_resources/_content.py,sha256=Vi-wZ-T5f-OqBGXkA3B9dALoFHer5F8LAQlc5x6pcls,14109
21
21
  unique_sdk/api_resources/_embedding.py,sha256=C6qak7cCUBMBINfPhgH8taCJZ9n6w1MUElqDJJ8dG10,1281
22
22
  unique_sdk/api_resources/_event.py,sha256=bpWF9vstdoAWbUzr-iiGP713ceP0zPk77GJXiImf9zg,374
23
23
  unique_sdk/api_resources/_folder.py,sha256=mIyWaxJtIHlDLPFZ0FY1U9b3dmtmIcjDEbgOZtLA-DI,12871
@@ -32,11 +32,11 @@ unique_sdk/api_resources/_search_string.py,sha256=4Idw6exgZdA8qksz9WkiA68k1hTU-7
32
32
  unique_sdk/api_resources/_short_term_memory.py,sha256=vPRN-Y0WPx74E6y-A3LocGc0TxJdzT-xGL66WzZwKRg,2820
33
33
  unique_sdk/api_resources/_space.py,sha256=6789zLwkoZqrEESiTJIBVaNi8kAKAZnqR0KMmW1AzgI,4905
34
34
  unique_sdk/utils/chat_history.py,sha256=5UqL9hF1O9pV7skbNOlEibF5rHdYsmG3m5-YEPUowOs,3037
35
- unique_sdk/utils/chat_in_space.py,sha256=3NeBjOu7p43V_6PrjwxyaTkgknUS10KE4QRuTlFDU_4,5232
35
+ unique_sdk/utils/chat_in_space.py,sha256=NrH9e2lvXtj_oePG0RWUqFoTanMblF8-VgtnVfszPS8,5949
36
36
  unique_sdk/utils/file_io.py,sha256=YY8B7VJcTLOPmCXByiOfNerXGlAtjCC5EVNmAbQJ3dQ,4306
37
37
  unique_sdk/utils/sources.py,sha256=DoxxhMLcLhmDfNarjXa41H4JD2GSSDywr71hiC-4pYc,4952
38
38
  unique_sdk/utils/token.py,sha256=AzKuAA1AwBtnvSFxGcsHLpxXr_wWE5Mj4jYBbOz2ljA,1740
39
- unique_sdk-0.10.17.dist-info/LICENSE,sha256=EJCWoHgrXVBUb47PnjeV4MFIEOR71MAdCOIgv61J-4k,1065
40
- unique_sdk-0.10.17.dist-info/METADATA,sha256=kqPSSpUqlgzvlDeR_-9bfF2LXNVtMv4WSCZZYtkht60,55043
41
- unique_sdk-0.10.17.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
42
- unique_sdk-0.10.17.dist-info/RECORD,,
39
+ unique_sdk-0.10.19.dist-info/LICENSE,sha256=EJCWoHgrXVBUb47PnjeV4MFIEOR71MAdCOIgv61J-4k,1065
40
+ unique_sdk-0.10.19.dist-info/METADATA,sha256=xppurAY1RbWZ-Z8BlMws7i_yZZhYY04pqxDj676FTpU,54448
41
+ unique_sdk-0.10.19.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
42
+ unique_sdk-0.10.19.dist-info/RECORD,,