unique_sdk 0.10.1__tar.gz → 0.10.3__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-0.10.1 → unique_sdk-0.10.3}/CHANGELOG.md +6 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/PKG-INFO +73 -28
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/README.md +66 -27
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/pyproject.toml +1 -1
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_content.py +11 -10
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_search.py +1 -0
- unique_sdk-0.10.3/unique_sdk/utils/chat_in_space.py +167 -0
- unique_sdk-0.10.1/unique_sdk/utils/chat_in_space.py +0 -53
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/LICENSE +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/__init__.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_api_requestor.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_api_resource.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_api_version.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_error.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_http_client.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_list_object.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_object_classes.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_request_options.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_unique_object.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_unique_ql.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_unique_response.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_util.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_version.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/_webhook.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/__init__.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_acronyms.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_chat_completion.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_embedding.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_event.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_folder.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_integrated.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_mcp.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_message.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_message_assessment.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_search_string.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_short_term_memory.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/api_resources/_space.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/utils/chat_history.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/utils/file_io.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/utils/sources.py +0 -0
- {unique_sdk-0.10.1 → unique_sdk-0.10.3}/unique_sdk/utils/token.py +0 -0
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.10.3] - 2025-08-05
|
|
9
|
+
- Expose scoreThreshold param for search.
|
|
10
|
+
|
|
11
|
+
## [0.10.2] - 2025-08-05
|
|
12
|
+
- Add script to chat against file.
|
|
13
|
+
|
|
8
14
|
## [0.10.1] - 2025-08-05
|
|
9
15
|
- Allow deletion of a space chat.
|
|
10
16
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: unique_sdk
|
|
3
|
-
Version: 0.10.
|
|
3
|
+
Version: 0.10.3
|
|
4
4
|
Summary:
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Martin Fadler
|
|
@@ -672,6 +672,7 @@ These are the options are available for `searchType`:
|
|
|
672
672
|
`language` Optional. The language specification for full text search.
|
|
673
673
|
`reranker` Optional. The reranker service to be used for re-ranking the search results.
|
|
674
674
|
`chatId` Optional, adds the documents uploaded in this chat to the scope of searched documents.
|
|
675
|
+
`scoreThreshold` Optional, sets the minimum similarity score for search results to be considered. Using 0 is recommended.
|
|
675
676
|
|
|
676
677
|
```python
|
|
677
678
|
search = unique_sdk.Search.create(
|
|
@@ -686,6 +687,7 @@ search = unique_sdk.Search.create(
|
|
|
686
687
|
reranker={"deploymentName": "my_deployment"},
|
|
687
688
|
limit=20,
|
|
688
689
|
page=1
|
|
690
|
+
scoreThreshold=0
|
|
689
691
|
)
|
|
690
692
|
```
|
|
691
693
|
|
|
@@ -1024,6 +1026,12 @@ A metadata filter such as the one designed above can be used in a `Search.create
|
|
|
1024
1026
|
|
|
1025
1027
|
## Utils
|
|
1026
1028
|
|
|
1029
|
+
- [Chat History](#chat-history)
|
|
1030
|
+
- [File Io](#file-io)
|
|
1031
|
+
- [Sources](#sources)
|
|
1032
|
+
- [token](#token)
|
|
1033
|
+
- [Chat In Space](#chat-in-space)
|
|
1034
|
+
|
|
1027
1035
|
### Chat History
|
|
1028
1036
|
|
|
1029
1037
|
#### `unique_sdk.utils.chat_history.load_history`
|
|
@@ -1253,33 +1261,64 @@ The script ensures you can flexibly interact with spaces in new or ongoing chats
|
|
|
1253
1261
|
|
|
1254
1262
|
```python
|
|
1255
1263
|
latest_message = await unique_sdk.utils.chat_in_space.send_message_and_wait_for_completion(
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1264
|
+
user_id=user_id,
|
|
1265
|
+
company_id=company_id,
|
|
1266
|
+
assistant_id=assistant_id,
|
|
1267
|
+
text="Tell me a short story.",
|
|
1268
|
+
chat_id=chat_id, # Optional - if no chat id is specified, a new chat will be created
|
|
1269
|
+
tool_choices=["WebSearch"],
|
|
1270
|
+
scope_rules={
|
|
1271
|
+
"or": [
|
|
1272
|
+
{
|
|
1273
|
+
"operator": "in",
|
|
1274
|
+
"path": [
|
|
1275
|
+
"contentId"
|
|
1276
|
+
],
|
|
1277
|
+
"value": [
|
|
1278
|
+
"cont_u888z7cazxxm4lugfdjq7pks"
|
|
1279
|
+
]
|
|
1280
|
+
},
|
|
1281
|
+
{
|
|
1282
|
+
"operator": "contains",
|
|
1283
|
+
"path": [
|
|
1284
|
+
"folderIdPath"
|
|
1285
|
+
],
|
|
1286
|
+
"value": "uniquepathid://scope_btfo28b3eeelwh5obwgea71bl/scope_fn56ta67knd6w4medgq3028fx"
|
|
1287
|
+
}
|
|
1288
|
+
]
|
|
1289
|
+
},
|
|
1290
|
+
)
|
|
1291
|
+
```
|
|
1292
|
+
|
|
1293
|
+
#### `unique_sdk.utils.chat_in_space.chat_against_file`
|
|
1294
|
+
|
|
1295
|
+
The following script enables you to chat against a file.
|
|
1296
|
+
|
|
1297
|
+
You must provide the following parameters:
|
|
1298
|
+
- `assistantId`: The assistant to be used for the chat.
|
|
1299
|
+
- `path_to_file`: The local path of the file to be uploaded.
|
|
1300
|
+
- `displayed_filename`: The name of the file to be displayed.
|
|
1301
|
+
- `mime_type`: The mime type of the ifle to be uploaded.
|
|
1302
|
+
- `text`: The text to be sent to the chat for chatting against the file.
|
|
1303
|
+
|
|
1304
|
+
The script creates a chat and uploads the file to it. It then keeps polling the `ingestionState` field of the message, waiting for it to reach `FINISHED`, signaling the upload is complete. Once the file uploads successfully, the script sends the text, continues polling for completion, and finally retrieves the response message.
|
|
1305
|
+
|
|
1306
|
+
**Optional parameters:**
|
|
1307
|
+
- `poll_interval`: The number of seconds to wait between polling attempts (default: `1` second).
|
|
1308
|
+
- `max_wait`: The maximum number of seconds to wait for the message to complete (default: `60` seconds).
|
|
1309
|
+
|
|
1310
|
+
Example of chatting against a PDF. (The usage can be extended to any supported file type)
|
|
1311
|
+
|
|
1312
|
+
```python
|
|
1313
|
+
latest_message = await unique_sdk.utils.chat_in_space.chat_against_file(
|
|
1314
|
+
user_id=user_id,
|
|
1315
|
+
company_id=company_id,
|
|
1316
|
+
assistant_id="assistant_hjcdga64bkcjnhu4",
|
|
1317
|
+
path_to_file="/files/hello.pdf",
|
|
1318
|
+
displayed_filename="hello.pdf"
|
|
1319
|
+
mime_type="application/pdf"
|
|
1320
|
+
text="Give me a bullet point summary of the file.",
|
|
1321
|
+
)
|
|
1283
1322
|
```
|
|
1284
1323
|
|
|
1285
1324
|
## Error Handling
|
|
@@ -1299,6 +1338,12 @@ All notable changes to this project will be documented in this file.
|
|
|
1299
1338
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
1300
1339
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
1301
1340
|
|
|
1341
|
+
## [0.10.3] - 2025-08-05
|
|
1342
|
+
- Expose scoreThreshold param for search.
|
|
1343
|
+
|
|
1344
|
+
## [0.10.2] - 2025-08-05
|
|
1345
|
+
- Add script to chat against file.
|
|
1346
|
+
|
|
1302
1347
|
## [0.10.1] - 2025-08-05
|
|
1303
1348
|
- Allow deletion of a space chat.
|
|
1304
1349
|
|
|
@@ -656,6 +656,7 @@ These are the options are available for `searchType`:
|
|
|
656
656
|
`language` Optional. The language specification for full text search.
|
|
657
657
|
`reranker` Optional. The reranker service to be used for re-ranking the search results.
|
|
658
658
|
`chatId` Optional, adds the documents uploaded in this chat to the scope of searched documents.
|
|
659
|
+
`scoreThreshold` Optional, sets the minimum similarity score for search results to be considered. Using 0 is recommended.
|
|
659
660
|
|
|
660
661
|
```python
|
|
661
662
|
search = unique_sdk.Search.create(
|
|
@@ -670,6 +671,7 @@ search = unique_sdk.Search.create(
|
|
|
670
671
|
reranker={"deploymentName": "my_deployment"},
|
|
671
672
|
limit=20,
|
|
672
673
|
page=1
|
|
674
|
+
scoreThreshold=0
|
|
673
675
|
)
|
|
674
676
|
```
|
|
675
677
|
|
|
@@ -1008,6 +1010,12 @@ A metadata filter such as the one designed above can be used in a `Search.create
|
|
|
1008
1010
|
|
|
1009
1011
|
## Utils
|
|
1010
1012
|
|
|
1013
|
+
- [Chat History](#chat-history)
|
|
1014
|
+
- [File Io](#file-io)
|
|
1015
|
+
- [Sources](#sources)
|
|
1016
|
+
- [token](#token)
|
|
1017
|
+
- [Chat In Space](#chat-in-space)
|
|
1018
|
+
|
|
1011
1019
|
### Chat History
|
|
1012
1020
|
|
|
1013
1021
|
#### `unique_sdk.utils.chat_history.load_history`
|
|
@@ -1237,33 +1245,64 @@ The script ensures you can flexibly interact with spaces in new or ongoing chats
|
|
|
1237
1245
|
|
|
1238
1246
|
```python
|
|
1239
1247
|
latest_message = await unique_sdk.utils.chat_in_space.send_message_and_wait_for_completion(
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1248
|
+
user_id=user_id,
|
|
1249
|
+
company_id=company_id,
|
|
1250
|
+
assistant_id=assistant_id,
|
|
1251
|
+
text="Tell me a short story.",
|
|
1252
|
+
chat_id=chat_id, # Optional - if no chat id is specified, a new chat will be created
|
|
1253
|
+
tool_choices=["WebSearch"],
|
|
1254
|
+
scope_rules={
|
|
1255
|
+
"or": [
|
|
1256
|
+
{
|
|
1257
|
+
"operator": "in",
|
|
1258
|
+
"path": [
|
|
1259
|
+
"contentId"
|
|
1260
|
+
],
|
|
1261
|
+
"value": [
|
|
1262
|
+
"cont_u888z7cazxxm4lugfdjq7pks"
|
|
1263
|
+
]
|
|
1264
|
+
},
|
|
1265
|
+
{
|
|
1266
|
+
"operator": "contains",
|
|
1267
|
+
"path": [
|
|
1268
|
+
"folderIdPath"
|
|
1269
|
+
],
|
|
1270
|
+
"value": "uniquepathid://scope_btfo28b3eeelwh5obwgea71bl/scope_fn56ta67knd6w4medgq3028fx"
|
|
1271
|
+
}
|
|
1272
|
+
]
|
|
1273
|
+
},
|
|
1274
|
+
)
|
|
1275
|
+
```
|
|
1276
|
+
|
|
1277
|
+
#### `unique_sdk.utils.chat_in_space.chat_against_file`
|
|
1278
|
+
|
|
1279
|
+
The following script enables you to chat against a file.
|
|
1280
|
+
|
|
1281
|
+
You must provide the following parameters:
|
|
1282
|
+
- `assistantId`: The assistant to be used for the chat.
|
|
1283
|
+
- `path_to_file`: The local path of the file to be uploaded.
|
|
1284
|
+
- `displayed_filename`: The name of the file to be displayed.
|
|
1285
|
+
- `mime_type`: The mime type of the ifle to be uploaded.
|
|
1286
|
+
- `text`: The text to be sent to the chat for chatting against the file.
|
|
1287
|
+
|
|
1288
|
+
The script creates a chat and uploads the file to it. It then keeps polling the `ingestionState` field of the message, waiting for it to reach `FINISHED`, signaling the upload is complete. Once the file uploads successfully, the script sends the text, continues polling for completion, and finally retrieves the response message.
|
|
1289
|
+
|
|
1290
|
+
**Optional parameters:**
|
|
1291
|
+
- `poll_interval`: The number of seconds to wait between polling attempts (default: `1` second).
|
|
1292
|
+
- `max_wait`: The maximum number of seconds to wait for the message to complete (default: `60` seconds).
|
|
1293
|
+
|
|
1294
|
+
Example of chatting against a PDF. (The usage can be extended to any supported file type)
|
|
1295
|
+
|
|
1296
|
+
```python
|
|
1297
|
+
latest_message = await unique_sdk.utils.chat_in_space.chat_against_file(
|
|
1298
|
+
user_id=user_id,
|
|
1299
|
+
company_id=company_id,
|
|
1300
|
+
assistant_id="assistant_hjcdga64bkcjnhu4",
|
|
1301
|
+
path_to_file="/files/hello.pdf",
|
|
1302
|
+
displayed_filename="hello.pdf"
|
|
1303
|
+
mime_type="application/pdf"
|
|
1304
|
+
text="Give me a bullet point summary of the file.",
|
|
1305
|
+
)
|
|
1267
1306
|
```
|
|
1268
1307
|
|
|
1269
1308
|
## Error Handling
|
|
@@ -64,6 +64,7 @@ class Content(APIResource["Content"]):
|
|
|
64
64
|
class SearchParams(RequestOptions):
|
|
65
65
|
where: "Content.ContentWhereInput"
|
|
66
66
|
chatId: NotRequired[str]
|
|
67
|
+
includeFailedContent: NotRequired[bool]
|
|
67
68
|
|
|
68
69
|
class ContentInfoParams(TypedDict):
|
|
69
70
|
"""
|
|
@@ -163,11 +164,11 @@ class Content(APIResource["Content"]):
|
|
|
163
164
|
class MagicTableSheetTable(TypedDict):
|
|
164
165
|
rowId: str
|
|
165
166
|
columns: List["Content.MagicTableSheetTableColumn"]
|
|
166
|
-
|
|
167
|
+
|
|
167
168
|
class MagicTableSheetIngestionConfiguration(TypedDict):
|
|
168
169
|
columnIdsInMetadata: List[str]
|
|
169
170
|
columnIdsInChunkText: List[str]
|
|
170
|
-
|
|
171
|
+
|
|
171
172
|
class MagicTableSheetIngestParams(TypedDict):
|
|
172
173
|
data: List["Content.MagicTableSheetTable"]
|
|
173
174
|
ingestionConfiguration: "Content.MagicTableSheetIngestionConfiguration"
|
|
@@ -298,10 +299,10 @@ class Content(APIResource["Content"]):
|
|
|
298
299
|
|
|
299
300
|
@classmethod
|
|
300
301
|
def ingest_magic_table_sheets(
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
302
|
+
cls,
|
|
303
|
+
user_id: str,
|
|
304
|
+
company_id: str,
|
|
305
|
+
**params: Unpack["Content.MagicTableSheetIngestParams"],
|
|
305
306
|
) -> "Content.MagicTableSheetResponse":
|
|
306
307
|
return cast(
|
|
307
308
|
Content.MagicTableSheetResponse,
|
|
@@ -316,10 +317,10 @@ class Content(APIResource["Content"]):
|
|
|
316
317
|
|
|
317
318
|
@classmethod
|
|
318
319
|
async def ingest_magic_table_sheets_async(
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
320
|
+
cls,
|
|
321
|
+
user_id: str,
|
|
322
|
+
company_id: str,
|
|
323
|
+
**params: Unpack["Content.MagicTableSheetIngestParams"],
|
|
323
324
|
) -> "Content.MagicTableSheetResponse":
|
|
324
325
|
return cast(
|
|
325
326
|
Content.MagicTableSheetResponse,
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
from unique_sdk.api_resources._content import Content
|
|
5
|
+
from unique_sdk.api_resources._space import Space
|
|
6
|
+
from unique_sdk.utils.file_io import upload_file
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
async def send_message_and_wait_for_completion(
|
|
10
|
+
user_id: str,
|
|
11
|
+
company_id: str,
|
|
12
|
+
assistant_id: str,
|
|
13
|
+
text: str,
|
|
14
|
+
tool_choices: List[str] = None,
|
|
15
|
+
scope_rules: dict | None = None,
|
|
16
|
+
chat_id: str = None,
|
|
17
|
+
poll_interval: float = 1.0,
|
|
18
|
+
max_wait: float = 60.0,
|
|
19
|
+
) -> "Space.Message":
|
|
20
|
+
"""
|
|
21
|
+
Sends a prompt asynchronously and polls for completion. (until stoppedStreamingAt is not None)
|
|
22
|
+
|
|
23
|
+
Args:
|
|
24
|
+
user_id: The user ID.
|
|
25
|
+
company_id: The company ID.
|
|
26
|
+
assistant_id: The assistant ID.
|
|
27
|
+
text: The prompt text.
|
|
28
|
+
poll_interval: Seconds between polls.
|
|
29
|
+
max_wait: Maximum seconds to wait for completion.
|
|
30
|
+
**kwargs: Additional parameters for the prompt.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
The completed Space.Message.
|
|
34
|
+
"""
|
|
35
|
+
response = await Space.create_message_async(
|
|
36
|
+
user_id=user_id,
|
|
37
|
+
company_id=company_id,
|
|
38
|
+
assistantId=assistant_id,
|
|
39
|
+
chatId=chat_id,
|
|
40
|
+
text=text,
|
|
41
|
+
toolChoices=tool_choices,
|
|
42
|
+
scopeRules=scope_rules,
|
|
43
|
+
)
|
|
44
|
+
chat_id = response.get("chatId")
|
|
45
|
+
|
|
46
|
+
max_attempts = int(max_wait // poll_interval)
|
|
47
|
+
for _ in range(max_attempts):
|
|
48
|
+
answer = Space.get_latest_message(user_id, company_id, chat_id)
|
|
49
|
+
if answer.get("stoppedStreamingAt") is not None:
|
|
50
|
+
return answer
|
|
51
|
+
await asyncio.sleep(poll_interval)
|
|
52
|
+
|
|
53
|
+
raise TimeoutError("Timed out waiting for prompt completion.")
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
async def chat_against_file(
|
|
57
|
+
user_id: str,
|
|
58
|
+
company_id: str,
|
|
59
|
+
assistant_id: str,
|
|
60
|
+
path_to_file: str,
|
|
61
|
+
displayed_filename: str,
|
|
62
|
+
mime_type: str,
|
|
63
|
+
text: str,
|
|
64
|
+
poll_interval: float = 1.0,
|
|
65
|
+
max_wait: float = 60.0,
|
|
66
|
+
) -> "Space.Message":
|
|
67
|
+
"""
|
|
68
|
+
Chat against a file by uploading it, sending a message and waiting for a reply.
|
|
69
|
+
Args:
|
|
70
|
+
|
|
71
|
+
user_id: The user ID.
|
|
72
|
+
company_id: The company ID.
|
|
73
|
+
assistant_id: The assistant ID.
|
|
74
|
+
path_to_file: Path to the PDF file to upload.
|
|
75
|
+
displayed_filename: Name to display for the uploaded file.
|
|
76
|
+
mime_type: MIME type of the file (e.g., "application/pdf").
|
|
77
|
+
text: Text to send after uploading the file and chat against.
|
|
78
|
+
poll_interval: Seconds between polls for file ingestion.
|
|
79
|
+
max_wait: Maximum seconds to wait for the final response.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
The final message response.
|
|
83
|
+
"""
|
|
84
|
+
chat_id = None
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
response = await send_message_and_wait_for_completion(
|
|
88
|
+
user_id=user_id,
|
|
89
|
+
company_id=company_id,
|
|
90
|
+
assistant_id=assistant_id,
|
|
91
|
+
text="I'm going to upload a file for analysis.",
|
|
92
|
+
)
|
|
93
|
+
chat_id = response.get("chatId")
|
|
94
|
+
|
|
95
|
+
upload_response = upload_file(
|
|
96
|
+
userId=user_id,
|
|
97
|
+
companyId=company_id,
|
|
98
|
+
path_to_file=path_to_file,
|
|
99
|
+
displayed_filename=displayed_filename,
|
|
100
|
+
mime_type=mime_type,
|
|
101
|
+
chat_id=chat_id,
|
|
102
|
+
)
|
|
103
|
+
content_id = upload_response.get("id")
|
|
104
|
+
|
|
105
|
+
await wait_for_ingestion_completion(
|
|
106
|
+
user_id=user_id,
|
|
107
|
+
company_id=company_id,
|
|
108
|
+
content_id=content_id,
|
|
109
|
+
chat_id=chat_id,
|
|
110
|
+
poll_interval=poll_interval,
|
|
111
|
+
max_wait=max_wait,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
final_response = await send_message_and_wait_for_completion(
|
|
115
|
+
user_id=user_id,
|
|
116
|
+
company_id=company_id,
|
|
117
|
+
assistant_id=assistant_id,
|
|
118
|
+
text=text,
|
|
119
|
+
chat_id=chat_id,
|
|
120
|
+
poll_interval=poll_interval,
|
|
121
|
+
max_wait=max_wait,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
return final_response
|
|
125
|
+
|
|
126
|
+
except Exception as err:
|
|
127
|
+
print(f"Error during chat against file: {err}")
|
|
128
|
+
raise
|
|
129
|
+
finally:
|
|
130
|
+
if chat_id:
|
|
131
|
+
Space.delete_chat(
|
|
132
|
+
user_id=user_id,
|
|
133
|
+
company_id=company_id,
|
|
134
|
+
chat_id=chat_id,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
async def wait_for_ingestion_completion(
|
|
139
|
+
user_id: str,
|
|
140
|
+
company_id: str,
|
|
141
|
+
content_id: str,
|
|
142
|
+
chat_id: str,
|
|
143
|
+
poll_interval: float = 1.0,
|
|
144
|
+
max_wait: float = 60.0,
|
|
145
|
+
):
|
|
146
|
+
"""
|
|
147
|
+
Waits until the content ingestionState is FINISHED or the maximum wait time is reached and throws if case of failed status.
|
|
148
|
+
"""
|
|
149
|
+
max_attempts = int(max_wait // poll_interval)
|
|
150
|
+
for _ in range(max_attempts):
|
|
151
|
+
searched_content = Content.search(
|
|
152
|
+
user_id=user_id,
|
|
153
|
+
company_id=company_id,
|
|
154
|
+
where={"id": {"equals": content_id}},
|
|
155
|
+
chatId=chat_id,
|
|
156
|
+
includeFailedContent=True,
|
|
157
|
+
)
|
|
158
|
+
if searched_content:
|
|
159
|
+
ingestion_state = searched_content[0].get("ingestionState")
|
|
160
|
+
if ingestion_state == "FINISHED":
|
|
161
|
+
return
|
|
162
|
+
if isinstance(ingestion_state, str) and ingestion_state.startswith(
|
|
163
|
+
"FAILED"
|
|
164
|
+
):
|
|
165
|
+
raise RuntimeError(f"Ingestion failed with state: {ingestion_state}")
|
|
166
|
+
await asyncio.sleep(poll_interval)
|
|
167
|
+
raise TimeoutError("Timed out waiting for file ingestion to finish.")
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
from typing import List
|
|
3
|
-
|
|
4
|
-
from unique_sdk.api_resources._space import Space
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
async def send_message_and_wait_for_completion(
|
|
8
|
-
user_id: str,
|
|
9
|
-
company_id: str,
|
|
10
|
-
assistant_id: str,
|
|
11
|
-
text: str,
|
|
12
|
-
tool_choices: List[str] = None,
|
|
13
|
-
scope_rules: dict | None = None,
|
|
14
|
-
chat_id: str = None,
|
|
15
|
-
poll_interval: float = 1.0,
|
|
16
|
-
max_wait: float = 60.0,
|
|
17
|
-
) -> "Space.Message":
|
|
18
|
-
"""
|
|
19
|
-
Sends a prompt asynchronously and polls for completion. (until stoppedStreamingAt is not None)
|
|
20
|
-
|
|
21
|
-
Args:
|
|
22
|
-
user_id: The user ID.
|
|
23
|
-
company_id: The company ID.
|
|
24
|
-
assistant_id: The assistant ID.
|
|
25
|
-
text: The prompt text.
|
|
26
|
-
poll_interval: Seconds between polls.
|
|
27
|
-
max_wait: Maximum seconds to wait for completion.
|
|
28
|
-
**kwargs: Additional parameters for the prompt.
|
|
29
|
-
|
|
30
|
-
Returns:
|
|
31
|
-
The completed Space.Message.
|
|
32
|
-
"""
|
|
33
|
-
# Send the prompt asynchronously
|
|
34
|
-
response = await Space.create_message_async(
|
|
35
|
-
user_id=user_id,
|
|
36
|
-
company_id=company_id,
|
|
37
|
-
assistantId=assistant_id,
|
|
38
|
-
chatId=chat_id,
|
|
39
|
-
text=text,
|
|
40
|
-
toolChoices=tool_choices,
|
|
41
|
-
scopeRules=scope_rules,
|
|
42
|
-
)
|
|
43
|
-
chat_id = response.get("chatId")
|
|
44
|
-
|
|
45
|
-
max_attempts = int(max_wait // poll_interval)
|
|
46
|
-
for _ in range(max_attempts):
|
|
47
|
-
# Poll for the answer
|
|
48
|
-
answer = Space.get_latest_message(user_id, company_id, chat_id)
|
|
49
|
-
if answer.get("stoppedStreamingAt") is not None:
|
|
50
|
-
return answer
|
|
51
|
-
await asyncio.sleep(poll_interval)
|
|
52
|
-
|
|
53
|
-
raise TimeoutError("Timed out waiting for prompt completion.")
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|