unique_sdk 0.10.51__py3-none-any.whl → 0.10.56__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_sdk/api_resources/_agentic_table.py +27 -17
- unique_sdk/api_resources/_folder.py +1 -0
- unique_sdk/api_resources/_integrated.py +1 -0
- unique_sdk-0.10.56.dist-info/METADATA +338 -0
- {unique_sdk-0.10.51.dist-info → unique_sdk-0.10.56.dist-info}/RECORD +7 -7
- unique_sdk-0.10.51.dist-info/METADATA +0 -2496
- {unique_sdk-0.10.51.dist-info → unique_sdk-0.10.56.dist-info}/LICENSE +0 -0
- {unique_sdk-0.10.51.dist-info → unique_sdk-0.10.56.dist-info}/WHEEL +0 -0
|
@@ -1,2496 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: unique_sdk
|
|
3
|
-
Version: 0.10.51
|
|
4
|
-
Summary:
|
|
5
|
-
License: MIT
|
|
6
|
-
Author: Martin Fadler
|
|
7
|
-
Author-email: martin.fadler@unique.ch
|
|
8
|
-
Requires-Python: >=3.11,<4.0
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
|
11
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
-
Provides-Extra: openai
|
|
14
|
-
Requires-Dist: openai (>=1.105.0,<2.0.0) ; extra == "openai"
|
|
15
|
-
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
|
16
|
-
Requires-Dist: typing-extensions (>=4.9.0,<5.0.0)
|
|
17
|
-
Description-Content-Type: text/markdown
|
|
18
|
-
|
|
19
|
-
# Unique Python SDK
|
|
20
|
-
|
|
21
|
-
Unique AI is a tailored solution for the financial industry, designed to increase productivity by automating manual workloads through AI and ChatGPT solutions.
|
|
22
|
-
|
|
23
|
-
The Unique Python SDK provides access to the public API of Unique AI. It also enables verification of Webhook signatures to ensure the authenticity of incoming Webhook requests.
|
|
24
|
-
|
|
25
|
-
## Table of Contents
|
|
26
|
-
|
|
27
|
-
1. [Installation](#installation)
|
|
28
|
-
2. [Requirements](#requirements)
|
|
29
|
-
3. [Usage Instructions](#usage-instructions)
|
|
30
|
-
4. [Webhook Triggers](#webhook-triggers)
|
|
31
|
-
5. [Available API Resources](#available-api-resources)
|
|
32
|
-
- [Content](#content)
|
|
33
|
-
- [Message](#message)
|
|
34
|
-
- [Message Log](#message-log)
|
|
35
|
-
- [Message Execution](#message-execution)
|
|
36
|
-
- [Chat Completion](#chat-completion)
|
|
37
|
-
- [Embeddings](#embeddings)
|
|
38
|
-
- [Acronyms](#acronyms)
|
|
39
|
-
- [Search](#search)
|
|
40
|
-
- [Search String](#search-string)
|
|
41
|
-
- [Short Term Memory](#short-term-memory)
|
|
42
|
-
- [Message Assessment](#message-assessment)
|
|
43
|
-
- [Folder](#folder)
|
|
44
|
-
- [Space](#space)
|
|
45
|
-
- [LLM Models](#llm-models)
|
|
46
|
-
- [User](#user)
|
|
47
|
-
- [Group](#group)
|
|
48
|
-
- [Agentic Table](#agentic-table)
|
|
49
|
-
6. [UniqueQL](#uniqueql)
|
|
50
|
-
- [Query Structure](#uniqueql-query-structure)
|
|
51
|
-
- [Metadata Filtering](#metadata-filtering)
|
|
52
|
-
7. [Util functions](#utils)
|
|
53
|
-
- [Chat History](#chat-history)
|
|
54
|
-
- [File Io](#file-io)
|
|
55
|
-
- [Sources](#sources)
|
|
56
|
-
- [token](#token)
|
|
57
|
-
- [Chat In Space](#chat-in-space)
|
|
58
|
-
8. [Error Handling](#error-handling)
|
|
59
|
-
9. [Examples](#examples)
|
|
60
|
-
|
|
61
|
-
## Installation
|
|
62
|
-
|
|
63
|
-
Install UniqueSDK and its peer dependency `requests` and when planning to run async requests also `httpx` or `aiohttp` via pip using the following commands:
|
|
64
|
-
|
|
65
|
-
```bash
|
|
66
|
-
pip install unique_sdk
|
|
67
|
-
pip install requests
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Optional for async requests:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
pip install httpx
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
or
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
pip install aiohttp
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Requirements
|
|
83
|
-
|
|
84
|
-
- Python >=3.11 (Other Python versions 3.6+ might work but are not tested)
|
|
85
|
-
- requests (peer dependency. Other HTTP request libraries might be supported in the future)
|
|
86
|
-
- Unique App-ID & API Key
|
|
87
|
-
|
|
88
|
-
Please contact your customer success manager at Unique for your personal developer App-ID & API Key.
|
|
89
|
-
|
|
90
|
-
## Usage instructions
|
|
91
|
-
|
|
92
|
-
The library needs to be configured with your Unique `app_id` & `api_key`. Additionally, each individual request must be scoped to a User and provide a `user_id` & `company_id`.
|
|
93
|
-
|
|
94
|
-
```python
|
|
95
|
-
import unique_sdk
|
|
96
|
-
unique_sdk.api_key = "ukey_..."
|
|
97
|
-
unique_sdk.app_id = "app_..."
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
The SDK includes a set of classes for API resources. Each class contains CRUD methods to interact with the resource.
|
|
101
|
-
|
|
102
|
-
### Example
|
|
103
|
-
|
|
104
|
-
```python
|
|
105
|
-
import unique_sdk
|
|
106
|
-
unique_sdk.api_key = "ukey_..."
|
|
107
|
-
unique_sdk.app_id = "app_..."
|
|
108
|
-
|
|
109
|
-
# list messages for a single chat
|
|
110
|
-
messages = unique_sdk.Message.list(
|
|
111
|
-
user_id=user_id,
|
|
112
|
-
company_id=company_id,
|
|
113
|
-
chatId=chat_id,
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
print(messages.data[0].text)
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Webhook Triggers
|
|
120
|
-
|
|
121
|
-
A core functionality of Unique AI is the ability for users to engage in an interactive chat feature. SDK developers can hook into this chat to provide new functionalities.
|
|
122
|
-
|
|
123
|
-
Your App (refer to `app-id` in [Requirements](#requirements)) must be subscribed to each individual Unique event in order to receive a webhook.
|
|
124
|
-
|
|
125
|
-
Each webhook sent by Unique includes a set of headers:
|
|
126
|
-
|
|
127
|
-
```yaml
|
|
128
|
-
X-Unique-Id: evt_... # Event id, same as in the body.
|
|
129
|
-
X-Unique-Signature: ... # A HMAC-SHA256 hex signature of the entire body.
|
|
130
|
-
X-Unique-Version: 1.0.0 # Event payload version.
|
|
131
|
-
X-Unique-Created-At: 1705960141 # Unix timestamp (seconds) of the delivery time.
|
|
132
|
-
X-Unique-User-Id: ... # The user who initiated the message.
|
|
133
|
-
X-Unique-Company-Id: ... # The company to which the user belongs.
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
### Success & Retry on Failure
|
|
137
|
-
|
|
138
|
-
- Webhooks are considered successfully delivered if your endpoint returns a status code between `200` and `299`.
|
|
139
|
-
- If your endpoint returns a status code of `300` - `399`, `429`, or `500` - `599`, Unique will retry the delivery of the webhook with an exponential backoff up to five times.
|
|
140
|
-
- If your endpoint returns any other status (e.g., `404`), it is marked as expired and will not receive any further requests.
|
|
141
|
-
|
|
142
|
-
### Webhook Signature Verification
|
|
143
|
-
|
|
144
|
-
The webhook body, containing a timestamp of the delivery time, is signed with HMAC-SHA256. Verify the signature by constructing the `event` with the `unique_sdk.Webhook` class:
|
|
145
|
-
|
|
146
|
-
```python
|
|
147
|
-
from http import HTTPStatus
|
|
148
|
-
from flask import Flask, jsonify, request
|
|
149
|
-
import unique_sdk
|
|
150
|
-
|
|
151
|
-
endpoint_secret = "YOUR_ENDPOINT_SECRET"
|
|
152
|
-
|
|
153
|
-
@app.route("/webhook", methods=["POST"])
|
|
154
|
-
def webhook():
|
|
155
|
-
event = None
|
|
156
|
-
payload = request.data
|
|
157
|
-
|
|
158
|
-
sig_header = request.headers.get("X-Unique-Signature")
|
|
159
|
-
timestamp = request.headers.get("X-Unique-Created-At")
|
|
160
|
-
|
|
161
|
-
if not sig_header or not timestamp:
|
|
162
|
-
print("⚠️ Webhook signature or timestamp headers missing.")
|
|
163
|
-
return jsonify(success=False), HTTPStatus.BAD_REQUEST
|
|
164
|
-
|
|
165
|
-
try:
|
|
166
|
-
event = unique_sdk.Webhook.construct_event(
|
|
167
|
-
payload, sig_header, timestamp, endpoint_secret
|
|
168
|
-
)
|
|
169
|
-
except unique_sdk.SignatureVerificationError as e:
|
|
170
|
-
print("⚠️ Webhook signature verification failed. " + str(e))
|
|
171
|
-
return jsonify(success=False), HTTPStatus.BAD_REQUEST
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
The `construct_event` method will compare the signature and raise a `unique_sdk.SignatureVerificationError` if the signature does not match. It will also raise this error if the `createdAt` timestamp is outside of a default tolerance of 5 minutes. Adjust the `tolerance` by passing a fifth parameter to the method (tolerance in seconds), e.g.:
|
|
175
|
-
|
|
176
|
-
```python
|
|
177
|
-
event = unique_sdk.Webhook.construct_event(
|
|
178
|
-
payload, sig_header, timestamp, endpoint_secret, 0
|
|
179
|
-
)
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
### Available Unique Events
|
|
183
|
-
|
|
184
|
-
#### User Message Created
|
|
185
|
-
|
|
186
|
-
```json
|
|
187
|
-
{
|
|
188
|
-
"id": "evt_...", // see header
|
|
189
|
-
"version": "1.0.0", // see header
|
|
190
|
-
"event": "unique.chat.user-message.created", // The name of the event
|
|
191
|
-
"createdAt": "1705960141", // see header
|
|
192
|
-
"userId": "...", // see header
|
|
193
|
-
"companyId": "...", // see header
|
|
194
|
-
"payload": {
|
|
195
|
-
"chatId": "chat_...", // The id of the chat
|
|
196
|
-
"assistantId": "assistant_...", // The id of the selected assistant
|
|
197
|
-
"text": "Hello, how can I help you?" // The user message
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
This webhook is triggered for every new chat message sent by the user. This event occurs regardless of whether it is the first or a subsequent message in a chat. Use the `unique_sdk.Message` class to retrieve other messages from the same `chatId` or maintain a local state of the messages in a single chat.
|
|
203
|
-
|
|
204
|
-
This trigger can be used in combination with assistants marked as `external`. Those assistants will not execute any logic, enabling your code to respond to the user message and create an answer.
|
|
205
|
-
|
|
206
|
-
#### External Module Chosen
|
|
207
|
-
|
|
208
|
-
```json
|
|
209
|
-
{
|
|
210
|
-
"id": "evt_...",
|
|
211
|
-
"version": "1.0.0",
|
|
212
|
-
"event": "unique.chat.external-module.chosen",
|
|
213
|
-
"createdAt": "1705960141", // Unix timestamp (seconds)
|
|
214
|
-
"userId": "...",
|
|
215
|
-
"companyId": "...",
|
|
216
|
-
"payload": {
|
|
217
|
-
"name": "example-sdk", // The name of the module selected by the module chooser
|
|
218
|
-
"description": "Example SDK", // The description of the module
|
|
219
|
-
"configuration": {}, // Module configuration in JSON format
|
|
220
|
-
"chatid": "chat_...", // The chat ID
|
|
221
|
-
"assistantId:": "assistant_...", // The assistant ID
|
|
222
|
-
"userMessage": {
|
|
223
|
-
"id": "msg_...",
|
|
224
|
-
"text": "Hello World!", // The user message leading to the module selection
|
|
225
|
-
"createdAt": "2024-01-01T00:00:00.000Z" // ISO 8601
|
|
226
|
-
},
|
|
227
|
-
"assistantMessage": {
|
|
228
|
-
"id": "msg_...",
|
|
229
|
-
"createdAt": "2024-01-01T00:00:00.000Z" // ISO 8601
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
This Webhook is triggered when the Unique AI selects an external module as the best response to a user message. The module must be marked as `external` and available for the assistant used in the chat to be selected by the AI.
|
|
236
|
-
|
|
237
|
-
Unique's UI will create an empty `assistantMessage` below the user message and update this message with status updates.
|
|
238
|
-
|
|
239
|
-
**The SDK is expected to modify this assistantMessage with its answer to the user message.**
|
|
240
|
-
|
|
241
|
-
```python
|
|
242
|
-
unique_sdk.Message.modify(
|
|
243
|
-
user_id=user_id,
|
|
244
|
-
company_id=company_id,
|
|
245
|
-
id=assistant_message_id,
|
|
246
|
-
chatId=chat_id,
|
|
247
|
-
text="Here is your answer.",
|
|
248
|
-
)
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## Available API Resources
|
|
252
|
-
|
|
253
|
-
- [Content](#content)
|
|
254
|
-
- [Message](#message)
|
|
255
|
-
- [Message Log](#message-log)
|
|
256
|
-
- [Message Execution](#message-execution)
|
|
257
|
-
- [Chat Completion](#chat-completion)
|
|
258
|
-
- [Embeddings](#embeddings)
|
|
259
|
-
- [Acronyms](#acronyms)
|
|
260
|
-
- [Search](#search)
|
|
261
|
-
- [Search String](#search-string)
|
|
262
|
-
- [Short Term Memory](#short-term-memory)
|
|
263
|
-
- [Message Assessment](#message-assessment)
|
|
264
|
-
- [Folder](#folder)
|
|
265
|
-
- [Space](#space)
|
|
266
|
-
- [LLM Models](#llm-models)
|
|
267
|
-
- [User](#user)
|
|
268
|
-
- [Group](#group)
|
|
269
|
-
- [Agentic Table](#agentic-table)
|
|
270
|
-
|
|
271
|
-
Most of the API services provide an asynchronous version of the method. The async methods are suffixed with `_async`.
|
|
272
|
-
|
|
273
|
-
### Content
|
|
274
|
-
|
|
275
|
-
#### `unique_sdk.Content.search`
|
|
276
|
-
|
|
277
|
-
Allows you to load full content/files from the knowledge-base of unique with the rights of the userId and companyId. Provided a `where` query for filtering. Filtering can be done on any of the following fields: `
|
|
278
|
-
|
|
279
|
-
- `id`
|
|
280
|
-
- `key`
|
|
281
|
-
- `ownerId`
|
|
282
|
-
- `title`
|
|
283
|
-
- `url`
|
|
284
|
-
|
|
285
|
-
Here an example of retrieving all files that contain the number 42 in the `title` or the `key` typically this is used to search by filename.
|
|
286
|
-
|
|
287
|
-
```python
|
|
288
|
-
unique_sdk.Content.search(
|
|
289
|
-
user_id=userId,
|
|
290
|
-
company_id=companyId,
|
|
291
|
-
where={
|
|
292
|
-
"OR": [
|
|
293
|
-
{
|
|
294
|
-
"title": {
|
|
295
|
-
"contains": "42",
|
|
296
|
-
},
|
|
297
|
-
},
|
|
298
|
-
{
|
|
299
|
-
"key": {
|
|
300
|
-
"contains": "42",
|
|
301
|
-
},
|
|
302
|
-
},
|
|
303
|
-
],
|
|
304
|
-
},
|
|
305
|
-
chatId=chatId,
|
|
306
|
-
)
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
#### `unique_sdk.Content.get_info`
|
|
310
|
-
|
|
311
|
-
[Deprecated, use `unique_sdk.Content.get_infos` instead.] Allows you to get content info. To filter the results you can define a metadata filter in UniqueQL language. Find out more about it in the UniqueQL section. An example of a metadata filter defined with UniqueQL is the following:
|
|
312
|
-
|
|
313
|
-
```python
|
|
314
|
-
metadataFilter: {
|
|
315
|
-
"or": [
|
|
316
|
-
{
|
|
317
|
-
"and": [
|
|
318
|
-
{
|
|
319
|
-
"operator": "contains",
|
|
320
|
-
"path": [
|
|
321
|
-
"folderIdPath"
|
|
322
|
-
],
|
|
323
|
-
"value": "uniquepathid://test_id"
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
"operator": "contains",
|
|
327
|
-
"path": [
|
|
328
|
-
"title"
|
|
329
|
-
],
|
|
330
|
-
"value": "ai"
|
|
331
|
-
}
|
|
332
|
-
]
|
|
333
|
-
}
|
|
334
|
-
]
|
|
335
|
-
},
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
Pagination is also enabled for this functionality, and the default number of returned results is 50 with no entries skipped. Use the following paramteres to get the desired page:`
|
|
339
|
-
|
|
340
|
-
- `skip`
|
|
341
|
-
- `take`
|
|
342
|
-
|
|
343
|
-
Here is an example of retrieving the first 3 content infos that contain the value `uniquepathid://scope_abcdibgznc4bkdcx120zm5d` in the `folderIdPath` metadata and the value `ai` for the `title` metadata.
|
|
344
|
-
|
|
345
|
-
```python
|
|
346
|
-
content_info_result = unique_sdk.Content.get_info(
|
|
347
|
-
user_id=user_id,
|
|
348
|
-
company_id=company_id,
|
|
349
|
-
metadataFilter={
|
|
350
|
-
"or": [
|
|
351
|
-
{
|
|
352
|
-
"and": [
|
|
353
|
-
{
|
|
354
|
-
"operator": "contains",
|
|
355
|
-
"path": [
|
|
356
|
-
"folderIdPath"
|
|
357
|
-
],
|
|
358
|
-
"value": "uniquepathid://scope_abcdibgznc4bkdcx120zm5d"
|
|
359
|
-
},
|
|
360
|
-
{
|
|
361
|
-
"operator": "contains",
|
|
362
|
-
"path": [
|
|
363
|
-
"title"
|
|
364
|
-
],
|
|
365
|
-
"value": "ai"
|
|
366
|
-
}
|
|
367
|
-
]
|
|
368
|
-
}
|
|
369
|
-
]
|
|
370
|
-
},
|
|
371
|
-
skip=0,
|
|
372
|
-
take=3,
|
|
373
|
-
)
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
#### `unique_sdk.Content.get_infos`
|
|
377
|
-
|
|
378
|
-
Allows you to get content infos. To filter the results you can define a either metadata filter in UniqueQL language or specify a parentId. If both are defined, the function will throw an error.
|
|
379
|
-
|
|
380
|
-
I f you want to learn more about UniqueQL, you can find out more about it in the [UniqueQL](#uniqueql) section. An example of a metadata filter defined with UniqueQL is the following:
|
|
381
|
-
|
|
382
|
-
```python
|
|
383
|
-
metadataFilter: {
|
|
384
|
-
"or": [
|
|
385
|
-
{
|
|
386
|
-
"and": [
|
|
387
|
-
{
|
|
388
|
-
"operator": "contains",
|
|
389
|
-
"path": [
|
|
390
|
-
"folderIdPath"
|
|
391
|
-
],
|
|
392
|
-
"value": "uniquepathid://test_id"
|
|
393
|
-
},
|
|
394
|
-
{
|
|
395
|
-
"operator": "contains",
|
|
396
|
-
"path": [
|
|
397
|
-
"title"
|
|
398
|
-
],
|
|
399
|
-
"value": "ai"
|
|
400
|
-
}
|
|
401
|
-
]
|
|
402
|
-
}
|
|
403
|
-
]
|
|
404
|
-
},
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
Pagination is also enabled for this functionality, and the default number of returned results is 50 with no entries skipped. Use the following paramteres to get the desired page:`
|
|
408
|
-
|
|
409
|
-
- `skip`
|
|
410
|
-
- `take`
|
|
411
|
-
|
|
412
|
-
Here is an example of retrieving the first 3 content infos that contain the value `uniquepathid://scope_abcdibgznc4bkdcx120zm5d` in the `folderIdPath` metadata and the value `ai` for the `title` metadata.
|
|
413
|
-
|
|
414
|
-
```python
|
|
415
|
-
content_info_result = unique_sdk.Content.get_infos(
|
|
416
|
-
user_id=user_id,
|
|
417
|
-
company_id=company_id,
|
|
418
|
-
metadataFilter={
|
|
419
|
-
"or": [
|
|
420
|
-
{
|
|
421
|
-
"and": [
|
|
422
|
-
{
|
|
423
|
-
"operator": "contains",
|
|
424
|
-
"path": [
|
|
425
|
-
"folderIdPath"
|
|
426
|
-
],
|
|
427
|
-
"value": "uniquepathid://scope_abcdibgznc4bkdcx120zm5d"
|
|
428
|
-
},
|
|
429
|
-
{
|
|
430
|
-
"operator": "contains",
|
|
431
|
-
"path": [
|
|
432
|
-
"title"
|
|
433
|
-
],
|
|
434
|
-
"value": "ai"
|
|
435
|
-
}
|
|
436
|
-
]
|
|
437
|
-
}
|
|
438
|
-
]
|
|
439
|
-
},
|
|
440
|
-
skip=0,
|
|
441
|
-
take=3,
|
|
442
|
-
)
|
|
443
|
-
```
|
|
444
|
-
|
|
445
|
-
Here is an example of retrieving the contents based on a parentId.
|
|
446
|
-
|
|
447
|
-
```python
|
|
448
|
-
content_info_result = unique_sdk.Content.get_infos(
|
|
449
|
-
user_id=user_id,
|
|
450
|
-
company_id=company_id,
|
|
451
|
-
parentId="scope_ahefgj389srjbfejkkk98u"
|
|
452
|
-
)
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
#### `unique_sdk.Content.upsert`
|
|
456
|
-
|
|
457
|
-
Enables upload of a new Content into the Knowledge base of unique into a specific scope with `scopeId` or a specific `chatId`. One of the two must be set.
|
|
458
|
-
|
|
459
|
-
Typical usage is the following. That creates a Content and uploads a file
|
|
460
|
-
|
|
461
|
-
```python
|
|
462
|
-
|
|
463
|
-
createdContent = upload_file(
|
|
464
|
-
userId,
|
|
465
|
-
companyId,
|
|
466
|
-
"/path/to/file.pdf",
|
|
467
|
-
"test.pdf",
|
|
468
|
-
"application/pdf",
|
|
469
|
-
"scope_stcj2osgbl722m22jayidx0n",
|
|
470
|
-
ingestionConfig={
|
|
471
|
-
"chunkMaxTokens": 1000,
|
|
472
|
-
"chunkStrategy": "default",
|
|
473
|
-
"uniqueIngestionMode": "standard",
|
|
474
|
-
},
|
|
475
|
-
metadata={
|
|
476
|
-
"folderIdPath": "uniquepathid://scope_id"
|
|
477
|
-
}
|
|
478
|
-
)
|
|
479
|
-
|
|
480
|
-
def upload_file(
|
|
481
|
-
userId,
|
|
482
|
-
companyId,
|
|
483
|
-
path_to_file,
|
|
484
|
-
displayed_filename,
|
|
485
|
-
mimeType,
|
|
486
|
-
description=None,
|
|
487
|
-
scope_or_unique_path,
|
|
488
|
-
ingestion_config=None,
|
|
489
|
-
metadata=None,
|
|
490
|
-
):
|
|
491
|
-
size = os.path.getsize(path_to_file)
|
|
492
|
-
createdContent = unique_sdk.Content.upsert(
|
|
493
|
-
user_id=userId,
|
|
494
|
-
company_id=companyId,
|
|
495
|
-
input={
|
|
496
|
-
"key": displayed_filename,
|
|
497
|
-
"title": displayed_filename,
|
|
498
|
-
"mimeType": mimeType,
|
|
499
|
-
"description": description,
|
|
500
|
-
"ingestionConfig": ingestionConfig,
|
|
501
|
-
"metadata": metadata,
|
|
502
|
-
},
|
|
503
|
-
scopeId=scope_or_unique_path,
|
|
504
|
-
)
|
|
505
|
-
|
|
506
|
-
uploadUrl = createdContent.writeUrl
|
|
507
|
-
|
|
508
|
-
# upload to azure blob storage SAS url uploadUrl the pdf file translatedFile make sure it is treated as a application/pdf
|
|
509
|
-
with open(path_to_file, "rb") as file:
|
|
510
|
-
requests.put(
|
|
511
|
-
uploadUrl,
|
|
512
|
-
data=file,
|
|
513
|
-
headers={
|
|
514
|
-
"X-Ms-Blob-Content-Type": mimeType,
|
|
515
|
-
"X-Ms-Blob-Type": "BlockBlob",
|
|
516
|
-
},
|
|
517
|
-
)
|
|
518
|
-
|
|
519
|
-
unique_sdk.Content.upsert(
|
|
520
|
-
user_id=userId,
|
|
521
|
-
company_id=companyId,
|
|
522
|
-
input={
|
|
523
|
-
"key": displayed_filename,
|
|
524
|
-
"title": displayed_filename,
|
|
525
|
-
"mimeType": mimeType,
|
|
526
|
-
"description": description,
|
|
527
|
-
"byteSize": size,
|
|
528
|
-
"ingestionConfig": ingestionConfig,
|
|
529
|
-
"metadata": metadata,
|
|
530
|
-
},
|
|
531
|
-
scopeId=scope_or_unique_path,
|
|
532
|
-
readUrl=createdContent.readUrl,
|
|
533
|
-
)
|
|
534
|
-
|
|
535
|
-
return createdContent
|
|
536
|
-
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
#### `unique_sdk.Content.ingest_magic_table_sheets`
|
|
540
|
-
|
|
541
|
-
Allows you to ingest a magic table sheet, each row is processed and converted into a content.
|
|
542
|
-
```python
|
|
543
|
-
params = {
|
|
544
|
-
"user_id": user_id,
|
|
545
|
-
"company_id": company_id,
|
|
546
|
-
"data": [
|
|
547
|
-
{
|
|
548
|
-
"rowId": "2",
|
|
549
|
-
"columns": [
|
|
550
|
-
{"columnId": "0", "columnName": "Section", "content": "Other"},
|
|
551
|
-
{"columnId": "1", "columnName": "Question", "content": "What do you know?"},
|
|
552
|
-
{
|
|
553
|
-
"columnId": "2",
|
|
554
|
-
"columnName": "Knowledge Base Answer",
|
|
555
|
-
"content": "Lorem Ipsum is simply dummy texktop publishing software.",
|
|
556
|
-
},
|
|
557
|
-
],
|
|
558
|
-
},
|
|
559
|
-
],
|
|
560
|
-
"ingestionConfiguration": {
|
|
561
|
-
"columnIdsInMetadata": ["1", "2"],
|
|
562
|
-
"columnIdsInChunkText": ["1", "2"],
|
|
563
|
-
},
|
|
564
|
-
"metadata": {
|
|
565
|
-
"libraryName": "foo",
|
|
566
|
-
},
|
|
567
|
-
"scopeId": scope_id,
|
|
568
|
-
"sheetName": "Sheet1",
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
unique_sdk.Content.ingest_magic_table_sheets(**params)
|
|
572
|
-
```
|
|
573
|
-
|
|
574
|
-
#### `unique_sdk.Content.update` (Compatible with release >.36)
|
|
575
|
-
|
|
576
|
-
Allows you to update a file specified by its `contentId` or by its `filePath`.
|
|
577
|
-
|
|
578
|
-
- `contentId` optional if `filePath` is provided, the id of the file to be updated
|
|
579
|
-
- `filePath` optional if `contentId` is provided, the absolute path of the file to be updated
|
|
580
|
-
|
|
581
|
-
Currently, the following updates are supported:
|
|
582
|
-
|
|
583
|
-
Title update:
|
|
584
|
-
- `title` optional, allows updating the title of the file
|
|
585
|
-
|
|
586
|
-
Move the file to a different folder. This can be done by specifying either the `ownerId` or the `parentFolderPath`.
|
|
587
|
-
- `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`.
|
|
588
|
-
- `parentFolderPath` optional, allows moving the file to a different folder. Represents the path new folder for the file.
|
|
589
|
-
|
|
590
|
-
Metadata update:
|
|
591
|
-
- `metadata` optional, allows updating the metadata of the file. Default metadata can not be overridden. (Available with release >.40)
|
|
592
|
-
|
|
593
|
-
Example of updating the title of a file specified by its path.
|
|
594
|
-
|
|
595
|
-
```python
|
|
596
|
-
unique_sdk.Content.update(
|
|
597
|
-
user_id=user_id,
|
|
598
|
-
company_id=company_id,
|
|
599
|
-
filePath="/Company/finance/january.xls",
|
|
600
|
-
title="Revision Deck"
|
|
601
|
-
)
|
|
602
|
-
```
|
|
603
|
-
|
|
604
|
-
Example of moving a file specified by its content id.
|
|
605
|
-
|
|
606
|
-
```python
|
|
607
|
-
unique_sdk.Content.update(
|
|
608
|
-
user_id=user_id,
|
|
609
|
-
company_id=company_id,
|
|
610
|
-
contentId="cont_ok2343q5owbce80w78hudawu5",
|
|
611
|
-
ownerId="scope_e68yz5asho7glfh7c7d041el",
|
|
612
|
-
metadata={
|
|
613
|
-
"quarter": "q1",
|
|
614
|
-
}
|
|
615
|
-
)
|
|
616
|
-
```
|
|
617
|
-
|
|
618
|
-
Example of moving a file and updating its title.
|
|
619
|
-
|
|
620
|
-
```python
|
|
621
|
-
unique_sdk.Content.update(
|
|
622
|
-
user_id=user_id,
|
|
623
|
-
company_id=company_id,
|
|
624
|
-
contentId="cont_ok2343q5owbce80w78hudawu5",
|
|
625
|
-
ownerId="scope_e68yz5asho7glfh7c7d041el",
|
|
626
|
-
title="Revision Deck (1)"
|
|
627
|
-
)
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
Example of moving a file to a folder specified by its path.
|
|
631
|
-
|
|
632
|
-
```python
|
|
633
|
-
unique_sdk.Content.update(
|
|
634
|
-
user_id=user_id,
|
|
635
|
-
company_id=company_id,
|
|
636
|
-
contentId="cont_ok2343q5owbce80w78hudawu5",
|
|
637
|
-
ownerId="scope_e68yz5asho7glfh7c7d041el",
|
|
638
|
-
parentFolderPath="/Company/Revisions"
|
|
639
|
-
)
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
#### `unique_sdk.Content.delete` (Compatible with release >.36)
|
|
643
|
-
|
|
644
|
-
Allows you to delete a file by its `contentId`. If the file is part of a chat, the `chatId` also needs do be set.
|
|
645
|
-
|
|
646
|
-
- `contentId` optional if `filePath` is provided, the id of the file to be deleted
|
|
647
|
-
- `chatId` optional, the id of the chat where the file is. Only needed if the file is part of a chat
|
|
648
|
-
- `filePath` optional if `contentId` is provided, the absolute path of the file to be deleted
|
|
649
|
-
|
|
650
|
-
Example of deleting a file from a chat.
|
|
651
|
-
|
|
652
|
-
```python
|
|
653
|
-
unique_sdk.Content.delete(
|
|
654
|
-
user_id=user_id,
|
|
655
|
-
company_id=company_id,
|
|
656
|
-
contentId="cont_ok2343q5owbce80w78hudawu5",
|
|
657
|
-
chatId="chat_v3xfa7liv876h89vuiibus1"
|
|
658
|
-
)
|
|
659
|
-
```
|
|
660
|
-
|
|
661
|
-
Example of deleting a file by its path.
|
|
662
|
-
|
|
663
|
-
```python
|
|
664
|
-
unique_sdk.Content.delete(
|
|
665
|
-
user_id=user_id,
|
|
666
|
-
company_id=company_id,
|
|
667
|
-
filePath="/Company/finance/january.xls",
|
|
668
|
-
)
|
|
669
|
-
```
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
### Message
|
|
673
|
-
|
|
674
|
-
#### `unique_sdk.Message.list`
|
|
675
|
-
|
|
676
|
-
Retrieve a list of messages for a provided `chatId`.
|
|
677
|
-
|
|
678
|
-
```python
|
|
679
|
-
messages = unique_sdk.Message.list(
|
|
680
|
-
user_id=user_id,
|
|
681
|
-
company_id=company_id,
|
|
682
|
-
chatId=chat_id,
|
|
683
|
-
)
|
|
684
|
-
```
|
|
685
|
-
|
|
686
|
-
#### `unique_sdk.Message.retrieve`
|
|
687
|
-
|
|
688
|
-
Get a single chat message.
|
|
689
|
-
|
|
690
|
-
```python
|
|
691
|
-
message = unique_sdk.Message.retrieve(
|
|
692
|
-
user_id=user_id,
|
|
693
|
-
company_id=company_id,
|
|
694
|
-
id=message_id,
|
|
695
|
-
chatId=chat_id,
|
|
696
|
-
)
|
|
697
|
-
```
|
|
698
|
-
|
|
699
|
-
#### `unique_sdk.Message.create`
|
|
700
|
-
|
|
701
|
-
Create a new message in a chat.
|
|
702
|
-
|
|
703
|
-
```python
|
|
704
|
-
message = unique_sdk.Message.create(
|
|
705
|
-
user_id=user_id,
|
|
706
|
-
company_id=company_id,
|
|
707
|
-
chatId=chat_id,
|
|
708
|
-
assistantId=assistant_id,
|
|
709
|
-
text="Hello.",
|
|
710
|
-
role="ASSISTANT",
|
|
711
|
-
)
|
|
712
|
-
```
|
|
713
|
-
|
|
714
|
-
#### `unique_sdk.Message.create_event`
|
|
715
|
-
|
|
716
|
-
Create a new message event in a chat. Updating the text of a message in the chat UI is possible by creating a message update event. This function can be used for custom streaming to the chat. (Compatible with release >.42)
|
|
717
|
-
|
|
718
|
-
The event only changes the text in the UI, it *does not* update the database.
|
|
719
|
-
|
|
720
|
-
```python
|
|
721
|
-
message = unique_sdk.Message.create_event(
|
|
722
|
-
user_id=user_id,
|
|
723
|
-
company_id=company_id,
|
|
724
|
-
messageId="msg_l4ushn85yqbewpf6tllh2cl7",
|
|
725
|
-
chatId="chat_kc8p3kgkn7393qhgmv5js5nt",
|
|
726
|
-
text="Hello.", #optional
|
|
727
|
-
originalText="Hello.", #optional
|
|
728
|
-
references=[], #optional
|
|
729
|
-
gptRequest={} #optional
|
|
730
|
-
debugInfo={ "hello": "test" }, #optional
|
|
731
|
-
)
|
|
732
|
-
```
|
|
733
|
-
|
|
734
|
-
#### `unique_sdk.Message.modify`
|
|
735
|
-
|
|
736
|
-
Modify an existing chat message.
|
|
737
|
-
|
|
738
|
-
ℹ️ if you modify the debugInfo only do it on the user message as this is the only place that is displayed in the frontend.
|
|
739
|
-
|
|
740
|
-
```python
|
|
741
|
-
message = unique_sdk.Message.modify(
|
|
742
|
-
user_id=user_id,
|
|
743
|
-
company_id=company_id,
|
|
744
|
-
id=message_id,
|
|
745
|
-
chatId=chat_id,
|
|
746
|
-
text="Updated message text"
|
|
747
|
-
)
|
|
748
|
-
```
|
|
749
|
-
|
|
750
|
-
#### `unique_sdk.Message.delete`
|
|
751
|
-
|
|
752
|
-
Delete a chat message.
|
|
753
|
-
|
|
754
|
-
```python
|
|
755
|
-
message = unique_sdk.Message.delete(
|
|
756
|
-
message_id,
|
|
757
|
-
user_id=user_id,
|
|
758
|
-
company_id=company_id,
|
|
759
|
-
chatId=chat_id,
|
|
760
|
-
)
|
|
761
|
-
```
|
|
762
|
-
|
|
763
|
-
#### `unique_sdk.Integrated.stream`
|
|
764
|
-
|
|
765
|
-
Streams the answer to the chat frontend. Given the messages.
|
|
766
|
-
|
|
767
|
-
if the stream creates [source0] it is referenced with the references from the search context.
|
|
768
|
-
|
|
769
|
-
E.g.
|
|
770
|
-
|
|
771
|
-
```
|
|
772
|
-
Hello this information is from [srouce1]
|
|
773
|
-
```
|
|
774
|
-
|
|
775
|
-
adds the reference at index 1 and then changes the text to:
|
|
776
|
-
|
|
777
|
-
```
|
|
778
|
-
Hello this information is from <sub>0</sub>
|
|
779
|
-
```
|
|
780
|
-
|
|
781
|
-
```python
|
|
782
|
-
unique_sdk.Integrated.chat_stream_completion(
|
|
783
|
-
user_id=userId,
|
|
784
|
-
company_id=companyId,
|
|
785
|
-
assistantMessageId=assistantMessageId,
|
|
786
|
-
userMessageId=userMessageId,
|
|
787
|
-
messages=[
|
|
788
|
-
{
|
|
789
|
-
"role": "system",
|
|
790
|
-
"content": "be friendly and helpful"
|
|
791
|
-
},
|
|
792
|
-
{
|
|
793
|
-
"role": "user",
|
|
794
|
-
"content": "hello"
|
|
795
|
-
}
|
|
796
|
-
],
|
|
797
|
-
chatId=chatId,
|
|
798
|
-
|
|
799
|
-
searchContext= [
|
|
800
|
-
{
|
|
801
|
-
"id": "ref_qavsg0dcl5cbfwm1fvgogrvo",
|
|
802
|
-
"chunkId": "0",
|
|
803
|
-
"key": "some reference.pdf : 8,9,10,11",
|
|
804
|
-
"sequenceNumber": 1,
|
|
805
|
-
"url": "unique://content/cont_p8n339trfsf99oc9f36rn4wf"
|
|
806
|
-
}
|
|
807
|
-
], # optional
|
|
808
|
-
debugInfo={
|
|
809
|
-
"hello": "test"
|
|
810
|
-
}, # optional
|
|
811
|
-
startText= "I want to tell you about: ", # optional
|
|
812
|
-
model= "AZURE_GPT_4_32K_0613", # optional
|
|
813
|
-
timeout=8000, # optional in ms
|
|
814
|
-
options={
|
|
815
|
-
"temperature": 0.5
|
|
816
|
-
} # optional
|
|
817
|
-
)
|
|
818
|
-
```
|
|
819
|
-
|
|
820
|
-
**Warning:** Currently, the deletion of a chat message does not automatically sync with the user UI. Users must refresh the chat page to view the updated state. This issue will be addressed in a future update of our API.
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
#### `unique_sdk.Integrated.responses_stream`
|
|
824
|
-
|
|
825
|
-
Streams the answer to the chat frontend using the Responses API. Given the messages.
|
|
826
|
-
|
|
827
|
-
if the stream creates [source0] it is referenced with the references from the search context.
|
|
828
|
-
|
|
829
|
-
E.g.
|
|
830
|
-
|
|
831
|
-
```
|
|
832
|
-
Hello this information is from [source1]
|
|
833
|
-
```
|
|
834
|
-
|
|
835
|
-
adds the reference at index 1 and then changes the text to:
|
|
836
|
-
|
|
837
|
-
```
|
|
838
|
-
Hello this information is from <sub>0</sub>
|
|
839
|
-
```
|
|
840
|
-
|
|
841
|
-
```python
|
|
842
|
-
unique_sdk.Integrated.responses_stream(
|
|
843
|
-
user_id=userId,
|
|
844
|
-
company_id=companyId,
|
|
845
|
-
model="AZURE_o3_2025_0416",
|
|
846
|
-
assistantMessageId=assistantMessageId,
|
|
847
|
-
userMessageId=userMessageId,
|
|
848
|
-
input="Tell me about the curious case of neural text degeneration",
|
|
849
|
-
chatId=chatId,
|
|
850
|
-
)
|
|
851
|
-
```
|
|
852
|
-
|
|
853
|
-
**Warning:** Currently, the deletion of a chat message does not automatically sync with the user UI. Users must refresh the chat page to view the updated state. This issue will be addressed in a future update of our API.
|
|
854
|
-
|
|
855
|
-
### Message Log
|
|
856
|
-
|
|
857
|
-
#### `unique_sdk.MessageLog.create`
|
|
858
|
-
|
|
859
|
-
Function to update the steps section of a message in the chat UI. This is possible by creating a message log record during a message execution.
|
|
860
|
-
|
|
861
|
-
```python
|
|
862
|
-
msg_log = unique_sdk.MessageLog.create(
|
|
863
|
-
user_id=user_id,
|
|
864
|
-
company_id=company_id,
|
|
865
|
-
messageId="msg_a0jgnt1jrqv1d3uzr450waxw",
|
|
866
|
-
text="Create message log text",
|
|
867
|
-
order=1,
|
|
868
|
-
status="RUNNING", # one of "RUNNING", "COMPLETED", "FAILED"
|
|
869
|
-
details={}, # optional, details dictionary
|
|
870
|
-
uncitedReferences={}, # optional, references dictionary
|
|
871
|
-
references=[], # optional, list of references
|
|
872
|
-
)
|
|
873
|
-
```
|
|
874
|
-
|
|
875
|
-
#### `unique_sdk.MessageLog.update`
|
|
876
|
-
|
|
877
|
-
Update a message log for a provided `messageId`.
|
|
878
|
-
|
|
879
|
-
```python
|
|
880
|
-
msg_log = unique_sdk.MessageLog.update(
|
|
881
|
-
user_id=user_id,
|
|
882
|
-
company_id=company_id,
|
|
883
|
-
message_log_id="message_log_fd7z7gjljo1z2wu5g6l9q7r9",
|
|
884
|
-
text="Update a message log text", # optional
|
|
885
|
-
order=1, # optional
|
|
886
|
-
status="RUNNING", # one of "RUNNING", "COMPLETED", "FAILED"
|
|
887
|
-
details={}, # optional, details dictionary
|
|
888
|
-
uncitedReferences={}, # optional, references dictionary
|
|
889
|
-
references=[], # optional, list of references
|
|
890
|
-
)
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
### Message Execution
|
|
894
|
-
|
|
895
|
-
#### `unique_sdk.MessageExecution.create`
|
|
896
|
-
|
|
897
|
-
Create a message execution for a provided `messageId` and `chatId`.
|
|
898
|
-
|
|
899
|
-
```python
|
|
900
|
-
msg_execution = unique_sdk.MessageExecution.create(
|
|
901
|
-
user_id=user_id,
|
|
902
|
-
company_id=company_id,
|
|
903
|
-
messageId="msg_a0jgnt1jrqv143uzr750waxw",
|
|
904
|
-
type="DEEP_RESEARCH",
|
|
905
|
-
)
|
|
906
|
-
```
|
|
907
|
-
|
|
908
|
-
#### `unique_sdk.MessageExecution.get`
|
|
909
|
-
|
|
910
|
-
Get a message execution for a provided `messageId`.
|
|
911
|
-
|
|
912
|
-
```python
|
|
913
|
-
msg_execution = unique_sdk.MessageExecution.get(
|
|
914
|
-
user_id=user_id,
|
|
915
|
-
company_id=company_id,
|
|
916
|
-
messageId="msg_a0jgnt1jrqv143uzr750waxw",
|
|
917
|
-
)
|
|
918
|
-
```
|
|
919
|
-
|
|
920
|
-
#### `unique_sdk.MessageExecution.update`
|
|
921
|
-
|
|
922
|
-
Update a message execution for a provided `messageId`.
|
|
923
|
-
|
|
924
|
-
```python
|
|
925
|
-
msg_execution = unique_sdk.MessageExecution.update(
|
|
926
|
-
user_id=user_id,
|
|
927
|
-
company_id=company_id,
|
|
928
|
-
messageId="msg_a0jgnt1jrqv143uzr750waxw",
|
|
929
|
-
status="COMPLETED", # optional, one of: COMPLETED, FAILED - not specifying the status will have no effect over the status
|
|
930
|
-
secondsRemaining=55, # optional, number defining the seconds remaining
|
|
931
|
-
percentageCompleted=10, # optional, number defining the percentage completed
|
|
932
|
-
)
|
|
933
|
-
```
|
|
934
|
-
|
|
935
|
-
### Chat Completion
|
|
936
|
-
|
|
937
|
-
#### `unique_sdk.ChatCompletion.create`
|
|
938
|
-
|
|
939
|
-
Send a prompt to an AI model supported by Unique AI and receive a result. The `messages` attribute must follow the [OpenAI API format](https://platform.openai.com/docs/api-reference/chat).
|
|
940
|
-
|
|
941
|
-
```python
|
|
942
|
-
chat_completion = unique_sdk.ChatCompletion.create(
|
|
943
|
-
company_id=company_id,
|
|
944
|
-
user_id=user_id
|
|
945
|
-
model="AZURE_GPT_4o_2024_1120",
|
|
946
|
-
messages=[
|
|
947
|
-
{"role": "system", "content": "You are a helpful assistant."},
|
|
948
|
-
{"role": "user", "content": "Hello!"},
|
|
949
|
-
],
|
|
950
|
-
options={
|
|
951
|
-
"temperature": 0.5, # optional
|
|
952
|
-
} # optional
|
|
953
|
-
)
|
|
954
|
-
```
|
|
955
|
-
|
|
956
|
-
### Embeddings
|
|
957
|
-
|
|
958
|
-
#### `unique_sdk.Embeddings.create`
|
|
959
|
-
|
|
960
|
-
Sends an array of `text` to the AI model for embedding. And retrieve a vector of embeddings.
|
|
961
|
-
|
|
962
|
-
```python
|
|
963
|
-
result = unique_sdk.Embeddings.create(
|
|
964
|
-
user_id=user_id,
|
|
965
|
-
company_id=company_id,
|
|
966
|
-
texts=["hello", "hello"],
|
|
967
|
-
)
|
|
968
|
-
print(result.embeddings[0][0])
|
|
969
|
-
```
|
|
970
|
-
|
|
971
|
-
### Acronyms
|
|
972
|
-
|
|
973
|
-
#### `unique_sdk.Acronyms.get`
|
|
974
|
-
|
|
975
|
-
Fetches the acronyms defined on the company. Often used to replace in user prompts, so the acronym is resolved to give better guidance to the LLM during completion.
|
|
976
|
-
|
|
977
|
-
```python
|
|
978
|
-
result = unique_sdk.Acronyms.get(
|
|
979
|
-
user_id=user_id,
|
|
980
|
-
company_id=company_id,
|
|
981
|
-
)
|
|
982
|
-
print(result)
|
|
983
|
-
```
|
|
984
|
-
|
|
985
|
-
### Search
|
|
986
|
-
|
|
987
|
-
#### `unique_sdk.Search.create`
|
|
988
|
-
|
|
989
|
-
Search the Unique AI Knowledge database for RAG (Retrieval-Augmented Generation). The API supports vector search and a `searchType` that combines vector and full-text search, enhancing the precision of search results.
|
|
990
|
-
|
|
991
|
-
These are the options are available for `searchType`:
|
|
992
|
-
|
|
993
|
-
- `VECTOR`
|
|
994
|
-
- `COMBINED`
|
|
995
|
-
|
|
996
|
-
`limit` (max 1000) and `page` are optional for iterating over results.
|
|
997
|
-
`chatOnly` Restricts the search exclusively to documents uploaded within the chat.
|
|
998
|
-
`scopeIds` Specifies a collection of scope IDs to confine the search.
|
|
999
|
-
`language` Optional. The language specification for full text search.
|
|
1000
|
-
`reranker` Optional. The reranker service to be used for re-ranking the search results.
|
|
1001
|
-
`chatId` Optional, adds the documents uploaded in this chat to the scope of searched documents.
|
|
1002
|
-
`scoreThreshold` Optional, sets the minimum similarity score for search results to be considered. Using 0 is recommended.
|
|
1003
|
-
|
|
1004
|
-
```python
|
|
1005
|
-
search = unique_sdk.Search.create(
|
|
1006
|
-
user_id=user_id,
|
|
1007
|
-
company_id=company_id,
|
|
1008
|
-
chatId=chat_id
|
|
1009
|
-
searchString="What is the meaning of life, the universe and everything?",
|
|
1010
|
-
searchType="VECTOR",
|
|
1011
|
-
chatOnly=false,
|
|
1012
|
-
scopeIds=["scope_..."],
|
|
1013
|
-
language="German",
|
|
1014
|
-
reranker={"deploymentName": "my_deployment"},
|
|
1015
|
-
limit=20,
|
|
1016
|
-
page=1
|
|
1017
|
-
scoreThreshold=0
|
|
1018
|
-
)
|
|
1019
|
-
```
|
|
1020
|
-
|
|
1021
|
-
### Search String
|
|
1022
|
-
|
|
1023
|
-
#### `unique_sdk.SearchString.create`
|
|
1024
|
-
|
|
1025
|
-
User messages are sometimes suboptimal as input prompts for vector or full-text knowledge base searches. This is particularly true as a conversation progresses and a user question may lack crucial context for a successful search.
|
|
1026
|
-
|
|
1027
|
-
This API transforms and translates (into English) the user's message into an ideal search string for use in the [Search.create](#unique_sdksearchcreate) API method.
|
|
1028
|
-
|
|
1029
|
-
Adding a `chatId` or `messages` as arguments allows the message history to provide additional context to the search string. For example, "Who is the author?" will be expanded to "Who is the author of the book 'The Hitchhiker's Guide to the Galaxy'?" if previous messages referenced the book.
|
|
1030
|
-
|
|
1031
|
-
```python
|
|
1032
|
-
search_string = unique_sdk.SearchString.create(
|
|
1033
|
-
user_id=user_id,
|
|
1034
|
-
company_id=company_id,
|
|
1035
|
-
prompt="Was ist der Sinn des Lebens, des Universums und des ganzen Rests?",
|
|
1036
|
-
chat_id=chat_id
|
|
1037
|
-
)
|
|
1038
|
-
```
|
|
1039
|
-
|
|
1040
|
-
### Short Term Memory
|
|
1041
|
-
|
|
1042
|
-
For saving data in between chats there is the Short Term Memory functionality to save small data in between rounds of chat e.g. language, search results and so on.
|
|
1043
|
-
For this 10k chars can be used. You can save a short term memory for a chat `chatId` or for a message `messageId`.
|
|
1044
|
-
you need to provide an `memoryName` as an identifier.
|
|
1045
|
-
|
|
1046
|
-
you can then save it and retreive it live defined below.
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
#### `unique_sdk.ShortTermMemory.create`
|
|
1050
|
-
|
|
1051
|
-
```python
|
|
1052
|
-
c = unique_sdk.ShortTermMemory.create(
|
|
1053
|
-
user_id=user_id,
|
|
1054
|
-
company_id=company_id,
|
|
1055
|
-
data="hello",
|
|
1056
|
-
chatId="chat_x0xxtj89f7drjp4vmued3q",
|
|
1057
|
-
# messageId = "msg_id",
|
|
1058
|
-
memoryName="your memory name",
|
|
1059
|
-
)
|
|
1060
|
-
print(c)
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
#### `unique_sdk.ShortTermMemory.find-latest`
|
|
1064
|
-
|
|
1065
|
-
```python
|
|
1066
|
-
m = unique_sdk.ShortTermMemory.find_latest(
|
|
1067
|
-
user_id=user_id,
|
|
1068
|
-
company_id=company_id,
|
|
1069
|
-
chatId="chat_x0xxtj89f7drjp4vmued3q",
|
|
1070
|
-
# messageId = "msg_id",
|
|
1071
|
-
memoryName="your memory name",
|
|
1072
|
-
)
|
|
1073
|
-
print(m)
|
|
1074
|
-
```
|
|
1075
|
-
|
|
1076
|
-
### Message Assessment
|
|
1077
|
-
|
|
1078
|
-
Used to create and modify message assessments for tracking hallucinations and compliance evaluations of assistant messages.
|
|
1079
|
-
|
|
1080
|
-
#### `unique_sdk.MessageAssessment.create`
|
|
1081
|
-
|
|
1082
|
-
Create a new message assessment for an assistant message.
|
|
1083
|
-
|
|
1084
|
-
```python
|
|
1085
|
-
assessment = unique_sdk.MessageAssessment.create(
|
|
1086
|
-
user_id=user_id,
|
|
1087
|
-
company_id=company_id,
|
|
1088
|
-
assistant_message_id="msg_...",
|
|
1089
|
-
status="DONE",
|
|
1090
|
-
explanation="This response contains incorrect information about...",
|
|
1091
|
-
label="RED",
|
|
1092
|
-
type="HALLUCINATION",
|
|
1093
|
-
title="Hallucination detected",
|
|
1094
|
-
isVisible=True
|
|
1095
|
-
)
|
|
1096
|
-
```
|
|
1097
|
-
|
|
1098
|
-
#### `unique_sdk.MessageAssessment.modify`
|
|
1099
|
-
|
|
1100
|
-
Modify an existing message assessment.
|
|
1101
|
-
|
|
1102
|
-
```python
|
|
1103
|
-
assessment = unique_sdk.MessageAssessment.modify(
|
|
1104
|
-
user_id=user_id,
|
|
1105
|
-
company_id=company_id,
|
|
1106
|
-
assistant_message_id="msg_...",
|
|
1107
|
-
status="DONE",
|
|
1108
|
-
explanation="Updated explanation...",
|
|
1109
|
-
label="RED",
|
|
1110
|
-
title="update title"
|
|
1111
|
-
type="HALLUCINATION"
|
|
1112
|
-
)
|
|
1113
|
-
```
|
|
1114
|
-
|
|
1115
|
-
### Folder
|
|
1116
|
-
|
|
1117
|
-
#### `unique_sdk.Folder.get_info`
|
|
1118
|
-
|
|
1119
|
-
Get a folder by scope id or by path.
|
|
1120
|
-
|
|
1121
|
-
By scope id:
|
|
1122
|
-
|
|
1123
|
-
```python
|
|
1124
|
-
unique_sdk.Folder.get_info(
|
|
1125
|
-
user_id=user_id,
|
|
1126
|
-
company_id=company_id,
|
|
1127
|
-
scopeId="scope_w78wfn114va9o22s13r03yq",
|
|
1128
|
-
)
|
|
1129
|
-
```
|
|
1130
|
-
|
|
1131
|
-
By path:
|
|
1132
|
-
|
|
1133
|
-
```python
|
|
1134
|
-
unique_sdk.Folder.get_info(
|
|
1135
|
-
user_id=user_id,
|
|
1136
|
-
company_id=company_id,
|
|
1137
|
-
folderPath="/Company/Atlas/Due Dilligence/Arch,
|
|
1138
|
-
)
|
|
1139
|
-
```
|
|
1140
|
-
|
|
1141
|
-
#### `unique_sdk.Folder.get_folder_path` (Compatible with release >.48)
|
|
1142
|
-
|
|
1143
|
-
Get the complete folder path for a given scope ID. Returns the full path string with folder names (e.g., "/company/subfolder1/subfolder2").
|
|
1144
|
-
|
|
1145
|
-
```python
|
|
1146
|
-
folder_path = unique_sdk.Folder.get_folder_path(
|
|
1147
|
-
user_id=user_id,
|
|
1148
|
-
company_id=company_id,
|
|
1149
|
-
scope_id="scope_w78wfn114va9o22s13r03yq",
|
|
1150
|
-
)
|
|
1151
|
-
```
|
|
1152
|
-
|
|
1153
|
-
#### `unique_sdl.Folder.get_infos`
|
|
1154
|
-
|
|
1155
|
-
Get paginated folders info based on parentId. If the parentId is not defined, the root folders will be returned.
|
|
1156
|
-
|
|
1157
|
-
```python
|
|
1158
|
-
unique_sdk.Folder.get_infos(
|
|
1159
|
-
user_id=user_id,
|
|
1160
|
-
company_id=company_id,
|
|
1161
|
-
take=10, #optional
|
|
1162
|
-
skip=5, #optional
|
|
1163
|
-
parentId="scope_s18seqpnltf35niydg77xgyp" #optional
|
|
1164
|
-
)
|
|
1165
|
-
```
|
|
1166
|
-
|
|
1167
|
-
#### `unique_sdk.Folder.create_paths`
|
|
1168
|
-
|
|
1169
|
-
Create each folder in the provided list of paths if it does not already exist.
|
|
1170
|
-
|
|
1171
|
-
```python
|
|
1172
|
-
unique_sdk.Folder.create_paths(
|
|
1173
|
-
user_id=user_id,
|
|
1174
|
-
company_id=company_id,
|
|
1175
|
-
paths=["/unique/path1", "/unique/path2"],
|
|
1176
|
-
)
|
|
1177
|
-
```
|
|
1178
|
-
|
|
1179
|
-
#### `unique_sdk.Folder.update_ingestion_config`
|
|
1180
|
-
|
|
1181
|
-
Allows you to update the ingestion config of a folder and choose whether to apply to the subscopes or not: `
|
|
1182
|
-
|
|
1183
|
-
- `ingestionConfig`
|
|
1184
|
-
- `applyToSubScopes`
|
|
1185
|
-
|
|
1186
|
-
The update can be done by referencing the folder by id or by path. If none of them are provided. the API will return an error. If both of them are provided, the scope id will take precedence.
|
|
1187
|
-
|
|
1188
|
-
Example of updating the ingestion config of a folder and its subfolders using the id.
|
|
1189
|
-
|
|
1190
|
-
```python
|
|
1191
|
-
unique_sdk.Folder.update_ingestion_config(
|
|
1192
|
-
user_id=user_id,
|
|
1193
|
-
company_id=company_id,
|
|
1194
|
-
scopeId="scope_qbnkde820dbmuw2900,
|
|
1195
|
-
ingestionConfig={
|
|
1196
|
-
"chunkStrategy": "default",
|
|
1197
|
-
"uniqueIngestionMode": "standard",
|
|
1198
|
-
},
|
|
1199
|
-
applyToSubScopes=True
|
|
1200
|
-
)
|
|
1201
|
-
```
|
|
1202
|
-
|
|
1203
|
-
Example of updating the ingestion config of a folder and its subfolders using the path.
|
|
1204
|
-
|
|
1205
|
-
```python
|
|
1206
|
-
unique_sdk.Folder.update_ingestion_config(
|
|
1207
|
-
user_id=user_id,
|
|
1208
|
-
company_id=company_id,
|
|
1209
|
-
folderPath="/Company/folder1/folder2",
|
|
1210
|
-
ingestionConfig={
|
|
1211
|
-
"chunkStrategy": "default",
|
|
1212
|
-
"uniqueIngestionMode": "standard",
|
|
1213
|
-
},
|
|
1214
|
-
applyToSubScopes=True
|
|
1215
|
-
)
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
#### `unique_sdk.Folder.add_access`
|
|
1219
|
-
|
|
1220
|
-
Allows you to add access to a folder and apply to the subfolders or not: `
|
|
1221
|
-
|
|
1222
|
-
- `scopeAccesses`
|
|
1223
|
-
- `applyToSubScopes`
|
|
1224
|
-
|
|
1225
|
-
The update can be done by referencing the folder by id or by path. If none of them are provided. the API will return an error. If both of them are provided, the scope id will take precedence.
|
|
1226
|
-
|
|
1227
|
-
Example of adding access to a folder and its subfolders using the id.
|
|
1228
|
-
|
|
1229
|
-
```python
|
|
1230
|
-
unique_sdk.Folder.add_access(
|
|
1231
|
-
user_id=user_id,
|
|
1232
|
-
company_id=company_id,
|
|
1233
|
-
scopeId="scope_231e4kjn4foffww34",
|
|
1234
|
-
scopeAccesses=[
|
|
1235
|
-
{
|
|
1236
|
-
"entityId": "group_id",
|
|
1237
|
-
"type": "WRITE",
|
|
1238
|
-
"entityType": "GROUP",
|
|
1239
|
-
}
|
|
1240
|
-
],
|
|
1241
|
-
applyToSubScopes=True,
|
|
1242
|
-
)
|
|
1243
|
-
```
|
|
1244
|
-
|
|
1245
|
-
Example of adding access to a folder and its subfolders using the folder path.
|
|
1246
|
-
|
|
1247
|
-
```python
|
|
1248
|
-
unique_sdk.Folder.add_access(
|
|
1249
|
-
user_id=user_id,
|
|
1250
|
-
company_id=company_id,
|
|
1251
|
-
folderPath="/Company/folder1/folder2"
|
|
1252
|
-
scopeAccesses=[
|
|
1253
|
-
{
|
|
1254
|
-
"entityId": "group_id",
|
|
1255
|
-
"type": "WRITE",
|
|
1256
|
-
"entityType": "GROUP",
|
|
1257
|
-
}
|
|
1258
|
-
],
|
|
1259
|
-
applyToSubScopes=True,
|
|
1260
|
-
)
|
|
1261
|
-
```
|
|
1262
|
-
|
|
1263
|
-
#### `unique_sdk.Folder.remove_access`
|
|
1264
|
-
|
|
1265
|
-
Allows you to delete access from a folder and apply to the subfolders or not:
|
|
1266
|
-
|
|
1267
|
-
- `scopeAccesses`
|
|
1268
|
-
- `applyToSubScopes`
|
|
1269
|
-
|
|
1270
|
-
The update can be done by referencing the folder by id or by path. If none of them are provided. the API will return an error. If both of them are provided, the scope id will take precedence.
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
Example of deleting the access from a folder and its subfolders using the id.
|
|
1274
|
-
|
|
1275
|
-
```python
|
|
1276
|
-
unique_sdk.Folder.remove_access(
|
|
1277
|
-
user_id=user_id,
|
|
1278
|
-
company_id=company_id,
|
|
1279
|
-
scopeId="scope_dwekjnf3330woioppm,
|
|
1280
|
-
scopeAccesses=[
|
|
1281
|
-
{
|
|
1282
|
-
"entityId": "group_id",
|
|
1283
|
-
"type": "WRITE",
|
|
1284
|
-
"entityType": "GROUP",
|
|
1285
|
-
}
|
|
1286
|
-
],
|
|
1287
|
-
applyToSubScopes=True,
|
|
1288
|
-
)
|
|
1289
|
-
```
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
Example of deleting the access from a folder and its subfolders using the path.
|
|
1293
|
-
|
|
1294
|
-
```python
|
|
1295
|
-
unique_sdk.Folder.remove_access(
|
|
1296
|
-
user_id=user_id,
|
|
1297
|
-
company_id=company_id,
|
|
1298
|
-
folderPath="/Company/folder1/folder2"
|
|
1299
|
-
scopeAccesses=[
|
|
1300
|
-
{
|
|
1301
|
-
"entityId": "group_id",
|
|
1302
|
-
"type": "WRITE",
|
|
1303
|
-
"entityType": "GROUP",
|
|
1304
|
-
}
|
|
1305
|
-
],
|
|
1306
|
-
applyToSubScopes=True,
|
|
1307
|
-
)
|
|
1308
|
-
```
|
|
1309
|
-
|
|
1310
|
-
#### `unique_sdk.Folder.update`
|
|
1311
|
-
Uupdate a folder specified by its `scopeId` or path. The following properties can be updated:
|
|
1312
|
-
- parent folder - move the folder to a new parent folder specified by its `scopeId` or path. If the new parent folder is the root folder, the `parentId` should be explicitly specificed by setting `newParentId` to `None`.
|
|
1313
|
-
- name - update the name by setting the `name` field to the new name.
|
|
1314
|
-
|
|
1315
|
-
Examples:
|
|
1316
|
-
|
|
1317
|
-
Move the folder specified by its `scopeId` to a new parent folder specified by its path.
|
|
1318
|
-
|
|
1319
|
-
```python
|
|
1320
|
-
unique_sdk.Folder.update(
|
|
1321
|
-
user_id=user_id,
|
|
1322
|
-
company_id=company_id,
|
|
1323
|
-
scopeId="scope_dwekjnf3330woioppm",
|
|
1324
|
-
parentFolderPath="/Company/folder1/folder2"
|
|
1325
|
-
)
|
|
1326
|
-
```
|
|
1327
|
-
|
|
1328
|
-
Move the parent of a folder specified by its path to a new parent folder specified by its `scopeId` and update the name to "January".
|
|
1329
|
-
|
|
1330
|
-
```python
|
|
1331
|
-
unique_sdk.Folder.update(
|
|
1332
|
-
user_id=user_id,
|
|
1333
|
-
company_id=company_id,
|
|
1334
|
-
folderPath="/Company/folder1",
|
|
1335
|
-
parentId="scope_dweekjrfhirtuhgroppm",
|
|
1336
|
-
name="January"
|
|
1337
|
-
)
|
|
1338
|
-
```
|
|
1339
|
-
|
|
1340
|
-
Move the parent of a folder specified by its path to the root folder and update the name to "January".
|
|
1341
|
-
|
|
1342
|
-
```python
|
|
1343
|
-
unique_sdk.Folder.update(
|
|
1344
|
-
user_id=user_id,
|
|
1345
|
-
company_id=company_id,
|
|
1346
|
-
folderPath="/Company/folder1",
|
|
1347
|
-
parentId=None,
|
|
1348
|
-
name="January"
|
|
1349
|
-
)
|
|
1350
|
-
```
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
#### `unique_sdk.Folder.delete` (Compatible with release >.36)
|
|
1354
|
-
|
|
1355
|
-
Given a `scopeId` or `folderPath`, the function deletes the folder. If the folder is not empty or if the user has no WRITE access, the delete will fail.
|
|
1356
|
-
|
|
1357
|
-
If `recursive` is set to true, the function also deletes its subfolders and its contents, behaving exactly like the `rm -rf`. In case a subfolder has no write access, that folder is considered as failed to delete and the function continues with the other subfolders. At the end, the function returns a list of `successFolders` and `failedFolders`.
|
|
1358
|
-
|
|
1359
|
-
Examples:
|
|
1360
|
-
Deleting recursively by scope id:
|
|
1361
|
-
|
|
1362
|
-
```python
|
|
1363
|
-
unique_sdk.Folder.delete(
|
|
1364
|
-
user_id=user_id,
|
|
1365
|
-
company_id=company_id,
|
|
1366
|
-
scopeId="scope_w78wfn114va9o22s13r03yq",
|
|
1367
|
-
recursive=True
|
|
1368
|
-
)
|
|
1369
|
-
```
|
|
1370
|
-
|
|
1371
|
-
Deleting by path (non-recursive):
|
|
1372
|
-
|
|
1373
|
-
```python
|
|
1374
|
-
unique_sdk.Folder.delete(
|
|
1375
|
-
user_id=user_id,
|
|
1376
|
-
company_id=company_id,
|
|
1377
|
-
folderPath="/Company/Atlas/Due Dilligence/Arch",
|
|
1378
|
-
)
|
|
1379
|
-
```
|
|
1380
|
-
|
|
1381
|
-
### Space
|
|
1382
|
-
|
|
1383
|
-
#### `unique_sdk.Space.create_message`
|
|
1384
|
-
|
|
1385
|
-
Send a message in a space. You can optionally provide a chat ID to continue an existing conversation, or omit it to start a new chat.
|
|
1386
|
-
|
|
1387
|
-
```python
|
|
1388
|
-
message = unique_sdk.Space.create_message(
|
|
1389
|
-
user_id=user_id,
|
|
1390
|
-
company_id=company_id,
|
|
1391
|
-
chatId="chat_dejfhe729br398", # Optional - if not provided, a new chat will be created
|
|
1392
|
-
assistantId="assistant_abc123",
|
|
1393
|
-
text="Hello, how can you help me?",
|
|
1394
|
-
toolChoices=["WebSearch"], # Optional - list of tools to use
|
|
1395
|
-
scopeRules={ # Optional - scope rules for filtering
|
|
1396
|
-
"or": [
|
|
1397
|
-
{
|
|
1398
|
-
"operator": "contains",
|
|
1399
|
-
"path": ["folderIdPath"],
|
|
1400
|
-
"value": "uniquepathid://scope_123"
|
|
1401
|
-
}
|
|
1402
|
-
]
|
|
1403
|
-
},
|
|
1404
|
-
)
|
|
1405
|
-
```
|
|
1406
|
-
|
|
1407
|
-
#### `unique_sdk.Space.get_chat_messages` (Compatible with release >.48)
|
|
1408
|
-
|
|
1409
|
-
Get all messages in a space chat. Returns a list of paginated messages in the specified chat.
|
|
1410
|
-
|
|
1411
|
-
```python
|
|
1412
|
-
messages = unique_sdk.Space.get_chat_messages(
|
|
1413
|
-
user_id=user_id,
|
|
1414
|
-
company_id=company_id,
|
|
1415
|
-
chat_id="chat_dejfhe729br398",
|
|
1416
|
-
skip=0, # Optional (defaults to 0) - number of messages to skip for pagination
|
|
1417
|
-
take=50, # Optional (defaults to 10) - number of messages to return
|
|
1418
|
-
)
|
|
1419
|
-
```
|
|
1420
|
-
|
|
1421
|
-
#### `unique_sdk.Space.get_latest_message`
|
|
1422
|
-
|
|
1423
|
-
Get the latest message in a space chat.
|
|
1424
|
-
|
|
1425
|
-
```python
|
|
1426
|
-
message = unique_sdk.Space.get_latest_message(
|
|
1427
|
-
user_id=user_id,
|
|
1428
|
-
company_id=company_id,
|
|
1429
|
-
chat_id="chat_dejfhe729br398",
|
|
1430
|
-
)
|
|
1431
|
-
```
|
|
1432
|
-
|
|
1433
|
-
#### `unique_sdk.Space.get_space` (Compatible with release >.48)
|
|
1434
|
-
|
|
1435
|
-
Get detailed information about a space, including its configuration, modules and scope rules.
|
|
1436
|
-
|
|
1437
|
-
```python
|
|
1438
|
-
space_info = unique_sdk.Space.get_space(
|
|
1439
|
-
user_id=user_id,
|
|
1440
|
-
company_id=company_id,
|
|
1441
|
-
space_id="assistant_hjcdga64bkcjnhu4",
|
|
1442
|
-
)
|
|
1443
|
-
```
|
|
1444
|
-
|
|
1445
|
-
#### `unique_sdk.Space.delete_chat`
|
|
1446
|
-
|
|
1447
|
-
Delete a space chat by id. If the chat does not exist, the function will return an error.
|
|
1448
|
-
|
|
1449
|
-
```python
|
|
1450
|
-
unique_sdk.Space.delete_chat(
|
|
1451
|
-
user_id=user_id,
|
|
1452
|
-
company_id=company_id,
|
|
1453
|
-
chat_id="chat_dejfhe729br398",
|
|
1454
|
-
)
|
|
1455
|
-
```
|
|
1456
|
-
|
|
1457
|
-
### LLM Models
|
|
1458
|
-
|
|
1459
|
-
#### `unique_sdk.LLMModels.get` (Compatible with release >.46)
|
|
1460
|
-
|
|
1461
|
-
Get available LLM models. You can optionally filter by module and skip cache to fetch fresh data.
|
|
1462
|
-
|
|
1463
|
-
```python
|
|
1464
|
-
models = unique_sdk.LLMModels.get(
|
|
1465
|
-
user_id=user_id,
|
|
1466
|
-
company_id=company_id,
|
|
1467
|
-
module="UNIQUE_AI", # Optional - filter models by module, only UNIQUE_AI is supported right now
|
|
1468
|
-
)
|
|
1469
|
-
```
|
|
1470
|
-
|
|
1471
|
-
### User
|
|
1472
|
-
|
|
1473
|
-
#### `unique_sdk.User.get_users` (Compatible with release >.48)
|
|
1474
|
-
|
|
1475
|
-
Get users in a company. You can filter by email, display name, and use pagination with skip and take parameters.
|
|
1476
|
-
|
|
1477
|
-
```python
|
|
1478
|
-
users = unique_sdk.User.get_users(
|
|
1479
|
-
user_id=user_id,
|
|
1480
|
-
company_id=company_id,
|
|
1481
|
-
skip=0, # Optional - number of records to skip for pagination
|
|
1482
|
-
take=50, # Optional - number of records to return (max 1000)
|
|
1483
|
-
email="user@example.com", # Optional - filter by email
|
|
1484
|
-
displayName="John", # Optional - filter by display name
|
|
1485
|
-
)
|
|
1486
|
-
```
|
|
1487
|
-
|
|
1488
|
-
#### `unique_sdk.User.update_user_configuration` (Compatible with release >.48)
|
|
1489
|
-
|
|
1490
|
-
Update the user configuration for the current user. The configuration is stored as a JSON object.
|
|
1491
|
-
|
|
1492
|
-
```python
|
|
1493
|
-
updated_user = unique_sdk.User.update_user_configuration(
|
|
1494
|
-
user_id=user_id,
|
|
1495
|
-
company_id=company_id,
|
|
1496
|
-
userConfiguration={ # Required - user configuration object (JSON)
|
|
1497
|
-
{"location": "CH"}
|
|
1498
|
-
}
|
|
1499
|
-
)
|
|
1500
|
-
```
|
|
1501
|
-
|
|
1502
|
-
### Group
|
|
1503
|
-
|
|
1504
|
-
#### `unique_sdk.Group.create_group` (Compatible with release >.48)
|
|
1505
|
-
|
|
1506
|
-
Create a new group in a company. You can specify the group name (required), external ID and parent group ID.
|
|
1507
|
-
|
|
1508
|
-
```python
|
|
1509
|
-
group = unique_sdk.Group.create_group(
|
|
1510
|
-
user_id=user_id,
|
|
1511
|
-
company_id=company_id,
|
|
1512
|
-
name="New Group", # Required - the name of the group
|
|
1513
|
-
externalId="ext_123", # Optional - external ID for the group
|
|
1514
|
-
parentId="group_a9cs7wr2z1bg2sxczvltgjch", # Optional - parent group ID
|
|
1515
|
-
)
|
|
1516
|
-
```
|
|
1517
|
-
|
|
1518
|
-
#### `unique_sdk.Group.get_groups` (Compatible with release >.48)
|
|
1519
|
-
|
|
1520
|
-
Get groups in a company. You can filter by name and use pagination with skip and take parameters.
|
|
1521
|
-
|
|
1522
|
-
```python
|
|
1523
|
-
groups = unique_sdk.Group.get_groups(
|
|
1524
|
-
user_id=user_id,
|
|
1525
|
-
company_id=company_id,
|
|
1526
|
-
skip=0, # Optional - number of records to skip for pagination
|
|
1527
|
-
take=50, # Optional - number of records to return (max 1000)
|
|
1528
|
-
name="Admin", # Optional - filter by group name
|
|
1529
|
-
)
|
|
1530
|
-
```
|
|
1531
|
-
|
|
1532
|
-
#### `unique_sdk.Group.update_group` (Compatible with release >.48)
|
|
1533
|
-
|
|
1534
|
-
Update a group in a company. You can update the group's name.
|
|
1535
|
-
|
|
1536
|
-
```python
|
|
1537
|
-
updated_group = unique_sdk.Group.update_group(
|
|
1538
|
-
user_id=user_id,
|
|
1539
|
-
company_id=company_id,
|
|
1540
|
-
group_id="group_a9cs7wr2z1bg2sxczvltgjch",
|
|
1541
|
-
name="New Group Name", # Optional - update the group name
|
|
1542
|
-
)
|
|
1543
|
-
```
|
|
1544
|
-
|
|
1545
|
-
#### `unique_sdk.Group.add_users_to_group` (Compatible with release >.48)
|
|
1546
|
-
|
|
1547
|
-
Add users to a group. Provide an array of user IDs to add as members to the specified group.
|
|
1548
|
-
|
|
1549
|
-
```python
|
|
1550
|
-
result = unique_sdk.Group.add_users_to_group(
|
|
1551
|
-
user_id=user_id,
|
|
1552
|
-
company_id=company_id,
|
|
1553
|
-
group_id="group_a9cs7wr2z1bg2sxczvltgjch",
|
|
1554
|
-
userIds=["299420877169688584", "325402458132058201", "299426678160031752"], # Required - array of user IDs to add
|
|
1555
|
-
)
|
|
1556
|
-
```
|
|
1557
|
-
|
|
1558
|
-
#### `unique_sdk.Group.remove_users_from_group` (Compatible with release >.48)
|
|
1559
|
-
|
|
1560
|
-
Remove users from a group. Provide an array of user IDs to remove from the specified group.
|
|
1561
|
-
|
|
1562
|
-
```python
|
|
1563
|
-
result = unique_sdk.Group.remove_users_from_group(
|
|
1564
|
-
user_id=user_id,
|
|
1565
|
-
company_id=company_id,
|
|
1566
|
-
group_id="group_a9cs7wr2z1bg2sxczvltgjch",
|
|
1567
|
-
userIds=["299426678160031752", "299426678160031752"], # Required - array of user IDs to remove
|
|
1568
|
-
)
|
|
1569
|
-
```
|
|
1570
|
-
|
|
1571
|
-
#### `unique_sdk.Group.update_group_configuration` (Compatible with release >.48)
|
|
1572
|
-
|
|
1573
|
-
Update the group configuration for the specified group. The configuration is stored as a JSON object.
|
|
1574
|
-
|
|
1575
|
-
```python
|
|
1576
|
-
updated_group = unique_sdk.Group.update_group_configuration(
|
|
1577
|
-
user_id=user_id,
|
|
1578
|
-
company_id=company_id,
|
|
1579
|
-
group_id="group_abc123",
|
|
1580
|
-
configuration={ # Required - group configuration object (JSON)
|
|
1581
|
-
{"email": "team@unique.ai"}
|
|
1582
|
-
}
|
|
1583
|
-
)
|
|
1584
|
-
```
|
|
1585
|
-
|
|
1586
|
-
#### `unique_sdk.Group.delete_group` (Compatible with release >.48)
|
|
1587
|
-
|
|
1588
|
-
Delete a group in a company by its group ID.
|
|
1589
|
-
|
|
1590
|
-
```python
|
|
1591
|
-
result = unique_sdk.Group.delete_group(
|
|
1592
|
-
user_id=user_id,
|
|
1593
|
-
company_id=company_id,
|
|
1594
|
-
group_id="group_a9cs7wr2z1bg2sxczvltgjch",
|
|
1595
|
-
)
|
|
1596
|
-
```
|
|
1597
|
-
|
|
1598
|
-
### Agentic Table
|
|
1599
|
-
|
|
1600
|
-
The Agentic Table (Magic Table) API provides functionality for managing interactive tables with AI-powered cells, activity tracking, and metadata management.
|
|
1601
|
-
|
|
1602
|
-
#### `unique_sdk.AgenticTable.set_cell`
|
|
1603
|
-
|
|
1604
|
-
Set the content of a specific cell in the magic table. This method allows you to update cell text and optionally add log entries to track changes.
|
|
1605
|
-
|
|
1606
|
-
```python
|
|
1607
|
-
cell = await unique_sdk.AgenticTable.set_cell(
|
|
1608
|
-
user_id=user_id,
|
|
1609
|
-
company_id=company_id,
|
|
1610
|
-
tableId="sheet_abc123",
|
|
1611
|
-
rowOrder=0,
|
|
1612
|
-
columnOrder=1,
|
|
1613
|
-
text="Updated cell content",
|
|
1614
|
-
logEntries=[ # optional
|
|
1615
|
-
{
|
|
1616
|
-
"text": "Cell updated by automation",
|
|
1617
|
-
"createdAt": "2024-01-01T00:00:00.000Z",
|
|
1618
|
-
"actorType": "SYSTEM", # One of: "USER", "SYSTEM", "ASSISTANT", "TOOL"
|
|
1619
|
-
"messageId": "msg_123", # optional
|
|
1620
|
-
"details": [ # optional
|
|
1621
|
-
{
|
|
1622
|
-
"text": "Processing completed",
|
|
1623
|
-
"messageId": "msg_456" # optional
|
|
1624
|
-
}
|
|
1625
|
-
]
|
|
1626
|
-
}
|
|
1627
|
-
]
|
|
1628
|
-
)
|
|
1629
|
-
```
|
|
1630
|
-
|
|
1631
|
-
#### `unique_sdk.AgenticTable.get_cell`
|
|
1632
|
-
|
|
1633
|
-
Retrieve the content and metadata of a specific cell.
|
|
1634
|
-
|
|
1635
|
-
```python
|
|
1636
|
-
cell = await unique_sdk.AgenticTable.get_cell(
|
|
1637
|
-
user_id=user_id,
|
|
1638
|
-
company_id=company_id,
|
|
1639
|
-
tableId="sheet_abc123",
|
|
1640
|
-
rowOrder=0,
|
|
1641
|
-
columnOrder=1,
|
|
1642
|
-
)
|
|
1643
|
-
```
|
|
1644
|
-
|
|
1645
|
-
#### `unique_sdk.AgenticTable.set_multiple_cells`
|
|
1646
|
-
|
|
1647
|
-
Bulk update multiple cells in a single operation for better performance.
|
|
1648
|
-
|
|
1649
|
-
```python
|
|
1650
|
-
result = await unique_sdk.AgenticTable.set_multiple_cells(
|
|
1651
|
-
user_id=user_id,
|
|
1652
|
-
company_id=company_id,
|
|
1653
|
-
tableId="sheet_abc123",
|
|
1654
|
-
cells=[
|
|
1655
|
-
{
|
|
1656
|
-
"rowOrder": 0,
|
|
1657
|
-
"columnOrder": 0,
|
|
1658
|
-
"text": "Cell A1"
|
|
1659
|
-
},
|
|
1660
|
-
{
|
|
1661
|
-
"rowOrder": 0,
|
|
1662
|
-
"columnOrder": 1,
|
|
1663
|
-
"text": "Cell B1"
|
|
1664
|
-
},
|
|
1665
|
-
{
|
|
1666
|
-
"rowOrder": 1,
|
|
1667
|
-
"columnOrder": 0,
|
|
1668
|
-
"text": "Cell A2"
|
|
1669
|
-
}
|
|
1670
|
-
]
|
|
1671
|
-
)
|
|
1672
|
-
```
|
|
1673
|
-
|
|
1674
|
-
#### `unique_sdk.AgenticTable.get_sheet_data`
|
|
1675
|
-
|
|
1676
|
-
Retrieve comprehensive data about a magic table sheet, including cells, log history, and metadata.
|
|
1677
|
-
|
|
1678
|
-
```python
|
|
1679
|
-
sheet = await unique_sdk.AgenticTable.get_sheet_data(
|
|
1680
|
-
user_id=user_id,
|
|
1681
|
-
company_id=company_id,
|
|
1682
|
-
tableId="sheet_abc123",
|
|
1683
|
-
includeCells=True, # optional
|
|
1684
|
-
includeLogHistory=True, # optional
|
|
1685
|
-
includeRowCount=True, # optional
|
|
1686
|
-
includeCellMetaData=True, # optional
|
|
1687
|
-
startRow=0, # optional: specify row range
|
|
1688
|
-
endRow=10 # optional: specify row range
|
|
1689
|
-
)
|
|
1690
|
-
```
|
|
1691
|
-
|
|
1692
|
-
#### `unique_sdk.AgenticTable.get_sheet_state`
|
|
1693
|
-
|
|
1694
|
-
Get the current state of a magic table sheet.
|
|
1695
|
-
|
|
1696
|
-
```python
|
|
1697
|
-
state = await unique_sdk.AgenticTable.get_sheet_state(
|
|
1698
|
-
user_id=user_id,
|
|
1699
|
-
company_id=company_id,
|
|
1700
|
-
tableId="sheet_abc123"
|
|
1701
|
-
)
|
|
1702
|
-
# Returns: "PROCESSING", "IDLE", or "STOPPED_BY_USER"
|
|
1703
|
-
```
|
|
1704
|
-
|
|
1705
|
-
#### `unique_sdk.AgenticTable.update_sheet_state`
|
|
1706
|
-
|
|
1707
|
-
Update the name or state of a magic table sheet.
|
|
1708
|
-
|
|
1709
|
-
```python
|
|
1710
|
-
result = await unique_sdk.AgenticTable.update_sheet_state(
|
|
1711
|
-
user_id=user_id,
|
|
1712
|
-
company_id=company_id,
|
|
1713
|
-
tableId="sheet_abc123",
|
|
1714
|
-
name="Updated Sheet Name", # optional
|
|
1715
|
-
state="IDLE" # optional, one of: "PROCESSING", "IDLE", "STOPPED_BY_USER"
|
|
1716
|
-
)
|
|
1717
|
-
```
|
|
1718
|
-
|
|
1719
|
-
#### `unique_sdk.AgenticTable.set_activity`
|
|
1720
|
-
|
|
1721
|
-
Set the status of an activity on the magic table sheet. This is useful for tracking long-running operations.
|
|
1722
|
-
|
|
1723
|
-
```python
|
|
1724
|
-
result = await unique_sdk.AgenticTable.set_activity(
|
|
1725
|
-
user_id=user_id,
|
|
1726
|
-
company_id=company_id,
|
|
1727
|
-
tableId="sheet_abc123",
|
|
1728
|
-
activity="UpdateCell",
|
|
1729
|
-
# activity: one of "DeleteRow", "DeleteColumn", "UpdateCell", "AddQuestionText",
|
|
1730
|
-
# "AddMetaData", "GenerateArtifact", "SheetCompleted", "LibrarySheetRowVerified"
|
|
1731
|
-
status="IN_PROGRESS",
|
|
1732
|
-
# status: one of "IN_PROGRESS", "COMPLETED", "FAILED"
|
|
1733
|
-
text="Updating cells with AI-generated content"
|
|
1734
|
-
)
|
|
1735
|
-
```
|
|
1736
|
-
|
|
1737
|
-
#### `unique_sdk.AgenticTable.set_artifact`
|
|
1738
|
-
|
|
1739
|
-
Attach an artifact (such as a generated document) to the magic table sheet.
|
|
1740
|
-
|
|
1741
|
-
```python
|
|
1742
|
-
result = await unique_sdk.AgenticTable.set_artifact(
|
|
1743
|
-
user_id=user_id,
|
|
1744
|
-
company_id=company_id,
|
|
1745
|
-
tableId="sheet_abc123",
|
|
1746
|
-
name="Generated Report",
|
|
1747
|
-
contentId="cont_xyz789",
|
|
1748
|
-
mimeType="application/pdf",
|
|
1749
|
-
artifactType="FULL_REPORT" # One of: "QUESTIONS", "FULL_REPORT"
|
|
1750
|
-
)
|
|
1751
|
-
```
|
|
1752
|
-
|
|
1753
|
-
#### `unique_sdk.AgenticTable.set_column_metadata`
|
|
1754
|
-
|
|
1755
|
-
Configure metadata for a specific column, including width, filters, and cell renderers.
|
|
1756
|
-
|
|
1757
|
-
```python
|
|
1758
|
-
result = await unique_sdk.AgenticTable.set_column_metadata(
|
|
1759
|
-
user_id=user_id,
|
|
1760
|
-
company_id=company_id,
|
|
1761
|
-
tableId="sheet_abc123",
|
|
1762
|
-
columnOrder=2,
|
|
1763
|
-
columnWidth=200, # optional
|
|
1764
|
-
filter="ValueMatchFilter", # optional
|
|
1765
|
-
# filter: one of "ValueMatchFilter", "PartialMatchFilter", "ReferenceFilter",
|
|
1766
|
-
# "HallucinationFilter", "ReviewStatusFilter", "AssigneeFilter"
|
|
1767
|
-
cellRenderer="CheckboxLockCellRenderer", # optional
|
|
1768
|
-
# cellRenderer: one of "CheckboxLockCellRenderer", "CollaboratorDropdown",
|
|
1769
|
-
# "ReviewStatusDropdown", "CustomCellRenderer", "SelectableCellRenderer"
|
|
1770
|
-
editable=True # optional
|
|
1771
|
-
)
|
|
1772
|
-
```
|
|
1773
|
-
|
|
1774
|
-
#### `unique_sdk.AgenticTable.set_cell_metadata`
|
|
1775
|
-
|
|
1776
|
-
Set metadata for a specific cell, including selection status and agreement status.
|
|
1777
|
-
|
|
1778
|
-
```python
|
|
1779
|
-
result = await unique_sdk.AgenticTable.set_cell_metadata(
|
|
1780
|
-
user_id=user_id,
|
|
1781
|
-
company_id=company_id,
|
|
1782
|
-
tableId="sheet_abc123",
|
|
1783
|
-
rowOrder=0,
|
|
1784
|
-
columnOrder=1,
|
|
1785
|
-
selected=True, # optional
|
|
1786
|
-
selectionMethod="MANUAL", # optional, one of: "DEFAULT", "MANUAL"
|
|
1787
|
-
agreementStatus="MATCH" # optional, one of: "MATCH", "NO_MATCH"
|
|
1788
|
-
)
|
|
1789
|
-
```
|
|
1790
|
-
|
|
1791
|
-
#### `unique_sdk.AgenticTable.bulk_update_status`
|
|
1792
|
-
|
|
1793
|
-
Update the verification status of multiple rows at once.
|
|
1794
|
-
|
|
1795
|
-
```python
|
|
1796
|
-
result = await unique_sdk.AgenticTable.bulk_update_status(
|
|
1797
|
-
user_id=user_id,
|
|
1798
|
-
company_id=company_id,
|
|
1799
|
-
tableId="sheet_abc123",
|
|
1800
|
-
rowOrders=[0, 1, 2, 3, 4],
|
|
1801
|
-
status="VERIFIED"
|
|
1802
|
-
# status: one of "NEED_REVIEW", "READY_FOR_VERIFICATION", "VERIFIED"
|
|
1803
|
-
)
|
|
1804
|
-
```
|
|
1805
|
-
|
|
1806
|
-
## UniqueQL
|
|
1807
|
-
|
|
1808
|
-
[UniqueQL](https://unique-ch.atlassian.net/wiki/x/coAXHQ) is an advanced query language designed to enhance search capabilities within various search modes such as Vector, Full-Text Search (FTS), and Combined. This query language enables users to perform detailed searches by filtering through metadata attributes like filenames, URLs, dates, and more. UniqueQL is versatile and can be translated into different query formats for various database systems, including PostgreSQL and Qdrant.
|
|
1809
|
-
|
|
1810
|
-
### UniqueQL Query Structure
|
|
1811
|
-
|
|
1812
|
-
A UniqueQL query is composed of a path, an operator, and a value. The path specifies the metadata attribute to be filtered, the operator defines the type of comparison, and the value provides the criteria for the filter.
|
|
1813
|
-
|
|
1814
|
-
A metadata filter can be designed with UniqueQL's `UQLOperator` and `UQLCombinator` as follows:
|
|
1815
|
-
|
|
1816
|
-
```python
|
|
1817
|
-
metadata_filter = {
|
|
1818
|
-
"path": ['diet', '*'],
|
|
1819
|
-
"operator": UQLOperator.NESTED,
|
|
1820
|
-
"value": {
|
|
1821
|
-
UQLCombinator.OR : [
|
|
1822
|
-
{
|
|
1823
|
-
UQLCombinator.OR: [
|
|
1824
|
-
{
|
|
1825
|
-
"path": ['food'],
|
|
1826
|
-
"operator": UQLOperator.EQUALS,
|
|
1827
|
-
"value": "meat",
|
|
1828
|
-
},
|
|
1829
|
-
{
|
|
1830
|
-
"path": ['food'],
|
|
1831
|
-
"operator": UQLOperator.EQUALS,
|
|
1832
|
-
"value": 'vegis',
|
|
1833
|
-
},
|
|
1834
|
-
],
|
|
1835
|
-
},
|
|
1836
|
-
{
|
|
1837
|
-
"path": ['likes'],
|
|
1838
|
-
"operator": UQLOperator.EQUALS,
|
|
1839
|
-
"value": true,
|
|
1840
|
-
},
|
|
1841
|
-
],
|
|
1842
|
-
},
|
|
1843
|
-
}
|
|
1844
|
-
```
|
|
1845
|
-
|
|
1846
|
-
### Metadata Filtering
|
|
1847
|
-
|
|
1848
|
-
A metadata filter such as the one designed above can be used in a `Search.create` call by passing it the `metaDataFilter` parameter.
|
|
1849
|
-
|
|
1850
|
-
```python
|
|
1851
|
-
search_results = unique_sdk.Search.create(
|
|
1852
|
-
user_id=user_id,
|
|
1853
|
-
company_id=company_id,
|
|
1854
|
-
chatId=chat_id,
|
|
1855
|
-
searchString=search_string,
|
|
1856
|
-
searchType="COMBINED",
|
|
1857
|
-
# limit=2,
|
|
1858
|
-
metaDataFilter=metadata_filter,
|
|
1859
|
-
)
|
|
1860
|
-
```
|
|
1861
|
-
|
|
1862
|
-
## Utils
|
|
1863
|
-
|
|
1864
|
-
- [Chat History](#chat-history)
|
|
1865
|
-
- [File Io](#file-io)
|
|
1866
|
-
- [Sources](#sources)
|
|
1867
|
-
- [token](#token)
|
|
1868
|
-
- [Chat In Space](#chat-in-space)
|
|
1869
|
-
|
|
1870
|
-
### Chat History
|
|
1871
|
-
|
|
1872
|
-
#### `unique_sdk.utils.chat_history.load_history`
|
|
1873
|
-
|
|
1874
|
-
A helper function that makes sure the chat history is fully loaded and cut to the size of the token window that it fits into the next round of chat interactions.
|
|
1875
|
-
|
|
1876
|
-
- `maxTokens` max tokens of the model used
|
|
1877
|
-
- `percentOfMaxTokens`=0.15 % max history in % of `maxTokens`
|
|
1878
|
-
- `maxMessages`=4, maximal number of messages included in the history.
|
|
1879
|
-
|
|
1880
|
-
this method also directly returns a correct formatted history that can be used in the next chat round.
|
|
1881
|
-
|
|
1882
|
-
```python
|
|
1883
|
-
history = unique_sdk.utils.chat_history.load_history(
|
|
1884
|
-
userId,
|
|
1885
|
-
companyId,
|
|
1886
|
-
chatId
|
|
1887
|
-
)
|
|
1888
|
-
```
|
|
1889
|
-
|
|
1890
|
-
#### `unique_sdk.utils.chat_history.convert_chat_history_to_injectable_string`
|
|
1891
|
-
|
|
1892
|
-
convert history into a string that can be injected into a prompt. it als returns the token length of the converted history.
|
|
1893
|
-
|
|
1894
|
-
```
|
|
1895
|
-
chat_history-string, chat_context_token_length = unique_sdk.utils.chat_history.convert_chat_history_to_injectable_string(
|
|
1896
|
-
history
|
|
1897
|
-
)
|
|
1898
|
-
```
|
|
1899
|
-
|
|
1900
|
-
### File Io
|
|
1901
|
-
|
|
1902
|
-
Interacting with the knowledge-base.
|
|
1903
|
-
|
|
1904
|
-
#### `unique_sdk.utils.file_io.download_content`
|
|
1905
|
-
|
|
1906
|
-
download files and save them into a folder in `/tmp`
|
|
1907
|
-
|
|
1908
|
-
for example using the readUrl from a content.
|
|
1909
|
-
|
|
1910
|
-
```python
|
|
1911
|
-
pdfFile = download_content(
|
|
1912
|
-
companyId=companyId,
|
|
1913
|
-
userId=userId,
|
|
1914
|
-
content_id="cont_12412",
|
|
1915
|
-
filename="hello.pdf",
|
|
1916
|
-
chat_id=None # If specified, it downloads it from the chat
|
|
1917
|
-
)
|
|
1918
|
-
```
|
|
1919
|
-
|
|
1920
|
-
#### `unique_sdk.utils.file_io.upload_file`
|
|
1921
|
-
|
|
1922
|
-
Allows for uploading files that then get ingested in a scope or a chat.
|
|
1923
|
-
|
|
1924
|
-
```python
|
|
1925
|
-
createdContent = upload_file(
|
|
1926
|
-
companyId=companyId,
|
|
1927
|
-
userId=userId,
|
|
1928
|
-
path_to_file="/tmp/hello.pdf",
|
|
1929
|
-
displayed_filename="hello.pdf",
|
|
1930
|
-
mime_type="application/pdf",
|
|
1931
|
-
scope_or_unique_path="scope_stcj2osgbl722m22jayidx0n",
|
|
1932
|
-
chat_id=None,
|
|
1933
|
-
)
|
|
1934
|
-
```
|
|
1935
|
-
|
|
1936
|
-
### Sources
|
|
1937
|
-
|
|
1938
|
-
#### `unique_sdk.utils.sources.merge_sources`
|
|
1939
|
-
|
|
1940
|
-
Merges multiple search results based on their 'id', removing redundant document and info markers.
|
|
1941
|
-
|
|
1942
|
-
This function groups search results by their 'id' and then concatenates their texts,
|
|
1943
|
-
cleaning up any document or info markers in subsequent chunks beyond the first one.
|
|
1944
|
-
|
|
1945
|
-
Parameters:
|
|
1946
|
-
|
|
1947
|
-
- searchContext (list): A list of dictionaries, each representing a search result with 'id' and 'text' keys.
|
|
1948
|
-
|
|
1949
|
-
Returns:
|
|
1950
|
-
|
|
1951
|
-
- list: A list of dictionaries with merged texts for each unique 'id'.
|
|
1952
|
-
|
|
1953
|
-
`searchContext` is an list of search objects that are returned by the search.
|
|
1954
|
-
|
|
1955
|
-
```python
|
|
1956
|
-
search = unique_sdk.Search.create(
|
|
1957
|
-
user_id=userId,
|
|
1958
|
-
company_id=companyId,
|
|
1959
|
-
chatId=chatId,
|
|
1960
|
-
searchString="Who is Harry P?",
|
|
1961
|
-
searchType="COMBINED",
|
|
1962
|
-
scopeIds="scope_dsf...",
|
|
1963
|
-
limit=30,
|
|
1964
|
-
chatOnly=False,
|
|
1965
|
-
)
|
|
1966
|
-
|
|
1967
|
-
searchContext = unique_sdk.utils.token.pick_search_results_for_token_window(
|
|
1968
|
-
search["data"], config["maxTokens"] - historyLength
|
|
1969
|
-
)
|
|
1970
|
-
|
|
1971
|
-
searchContext = unique_sdk.utils.sources.merge_sources(search)
|
|
1972
|
-
|
|
1973
|
-
```
|
|
1974
|
-
|
|
1975
|
-
#### `unique_sdk.utils.sources.sort_sources`
|
|
1976
|
-
|
|
1977
|
-
Sort sources by order of appearance in documents
|
|
1978
|
-
|
|
1979
|
-
```python
|
|
1980
|
-
|
|
1981
|
-
search = unique_sdk.Search.create(
|
|
1982
|
-
user_id=userId,
|
|
1983
|
-
company_id=companyId,
|
|
1984
|
-
chatId=chatId,
|
|
1985
|
-
searchString="Who is Harry P?",
|
|
1986
|
-
searchType="COMBINED",
|
|
1987
|
-
scopeIds="scope_dsf...",
|
|
1988
|
-
limit=30,
|
|
1989
|
-
chatOnly=False,
|
|
1990
|
-
)
|
|
1991
|
-
|
|
1992
|
-
searchContext = unique_sdk.utils.token.pick_search_results_for_token_window(
|
|
1993
|
-
search["data"], config["maxTokens"] - historyLength
|
|
1994
|
-
)
|
|
1995
|
-
|
|
1996
|
-
searchContext = unique_sdk.utils.sources.sort_sources(search)
|
|
1997
|
-
```
|
|
1998
|
-
|
|
1999
|
-
#### `unique_sdk.utils.sources.post_process_sources`
|
|
2000
|
-
|
|
2001
|
-
Post-processes the provided text by converting source references into superscript numerals (required
|
|
2002
|
-
format by backend to display sources in the chat window)
|
|
2003
|
-
|
|
2004
|
-
This function searches the input text for patterns that represent source references (e.g., [source1])
|
|
2005
|
-
and replaces them with superscript tags, incrementing the number by one.
|
|
2006
|
-
|
|
2007
|
-
Parameters:
|
|
2008
|
-
|
|
2009
|
-
- text (str): The text to be post-processed.
|
|
2010
|
-
|
|
2011
|
-
Returns:
|
|
2012
|
-
|
|
2013
|
-
- str: The text with source references replaced by superscript numerals.
|
|
2014
|
-
|
|
2015
|
-
Examples:
|
|
2016
|
-
|
|
2017
|
-
- postprocessSources("This is a reference [source0]") will return "This is a reference <sup>1</sup>".
|
|
2018
|
-
|
|
2019
|
-
```python
|
|
2020
|
-
|
|
2021
|
-
text_with_sup = post_process_sources(text)
|
|
2022
|
-
```
|
|
2023
|
-
|
|
2024
|
-
### Token
|
|
2025
|
-
|
|
2026
|
-
#### unique_sdk.utils.token.pick_search_results_for_token_window
|
|
2027
|
-
|
|
2028
|
-
Selects and returns a list of search results that fit within a specified token limit.
|
|
2029
|
-
|
|
2030
|
-
This function iterates over a list of search results, each with a 'text' field, and
|
|
2031
|
-
encodes the text using a predefined encoding scheme. It accumulates search results
|
|
2032
|
-
until the token limit is reached or exceeded.
|
|
2033
|
-
|
|
2034
|
-
Parameters:
|
|
2035
|
-
|
|
2036
|
-
- searchResults (list): A list of dictionaries, each containing a 'text' key with string value.
|
|
2037
|
-
- tokenLimit (int): The maximum number of tokens to include in the output.
|
|
2038
|
-
|
|
2039
|
-
Returns:
|
|
2040
|
-
|
|
2041
|
-
- list: A list of dictionaries representing the search results that fit within the token limit.
|
|
2042
|
-
|
|
2043
|
-
```python
|
|
2044
|
-
search = unique_sdk.Search.create(
|
|
2045
|
-
user_id=userId,
|
|
2046
|
-
company_id=companyId,
|
|
2047
|
-
chatId=chatId,
|
|
2048
|
-
searchString="Who is Harry P?",
|
|
2049
|
-
searchType="COMBINED",
|
|
2050
|
-
scopeIds="scope_dsf...",
|
|
2051
|
-
limit=30,
|
|
2052
|
-
chatOnly=False,
|
|
2053
|
-
)
|
|
2054
|
-
|
|
2055
|
-
searchContext = unique_sdk.utils.token.pick_search_results_for_token_window(
|
|
2056
|
-
search["data"], config["maxTokens"] - historyLength
|
|
2057
|
-
)
|
|
2058
|
-
```
|
|
2059
|
-
|
|
2060
|
-
#### unique_sdk.utils.token.count_tokens
|
|
2061
|
-
|
|
2062
|
-
Counts the number of tokens in the provided text.
|
|
2063
|
-
|
|
2064
|
-
This function encodes the input text using a predefined encoding scheme
|
|
2065
|
-
and returns the number of tokens in the encoded text.
|
|
2066
|
-
|
|
2067
|
-
Parameters:
|
|
2068
|
-
|
|
2069
|
-
- text (str): The text to count tokens for.
|
|
2070
|
-
|
|
2071
|
-
Returns:
|
|
2072
|
-
|
|
2073
|
-
- int: The number of tokens in the text.
|
|
2074
|
-
|
|
2075
|
-
```python
|
|
2076
|
-
hello = "hello you!"
|
|
2077
|
-
searchContext = unique_sdk.utils.token.count_tokens(hello)
|
|
2078
|
-
```
|
|
2079
|
-
|
|
2080
|
-
### Chat In Space
|
|
2081
|
-
|
|
2082
|
-
#### `unique_sdk.utils.chat_in_space.send_message_and_wait_for_completion`
|
|
2083
|
-
|
|
2084
|
-
The following script enables you to chat within a space using an assistant. You must provide an `assistantId` (e.g., `assistant_hjcdga64bkcjnhu4`) and the message `text` to initiate the conversation. You can send the message in an existing chat by specifying a `chat_id`, or omit the `chat_id` to automatically create a new chat session. Check the optional parameteres list for more configs.
|
|
2085
|
-
|
|
2086
|
-
The script sends a prompt asynchronously and continuously polls for completion, which is determined when the `stoppedStreamingAt` field of the message becomes non-null.
|
|
2087
|
-
|
|
2088
|
-
**Optional parameters:**
|
|
2089
|
-
- `tool_choices`: A list of tool names to be used for the message (e.g., `["WebSearch"]`). If not provided, no tools will be used. The tools supported right now are `WebSearch` and `InternalSearch`.
|
|
2090
|
-
- `scope_rules`: A filter to specify the scope rules for the message, allowing you to restrict the context or data sources available to the assistant. The filter is written in UniqueQL language. Find out more about the language in the UniqueQL section.
|
|
2091
|
-
- `chat_id`: The ID of the chat where the message should be sent. If omitted, a new chat will be created.
|
|
2092
|
-
- `poll_interval`: The number of seconds to wait between polling attempts (default: `1` second).
|
|
2093
|
-
- `max_wait`: The maximum number of seconds to wait for the message to complete (default: `60` seconds).
|
|
2094
|
-
- `stop_condition`: Defines when to expect a response back, when the assistant stop streaming or when it completes the message. (default: "stoppedStreamingAt")
|
|
2095
|
-
|
|
2096
|
-
The script ensures you can flexibly interact with spaces in new or ongoing chats, with fine-grained control over tools, context, and polling behavior.
|
|
2097
|
-
|
|
2098
|
-
```python
|
|
2099
|
-
from unique_sdk.utils.chat_in_space import send_message_and_wait_for_completion
|
|
2100
|
-
latest_message = await send_message_and_wait_for_completion(
|
|
2101
|
-
user_id=user_id,
|
|
2102
|
-
company_id=company_id,
|
|
2103
|
-
assistant_id=assistant_id,
|
|
2104
|
-
text="Tell me a short story.",
|
|
2105
|
-
chat_id=chat_id, # Optional - if no chat id is specified, a new chat will be created
|
|
2106
|
-
tool_choices=["WebSearch"],
|
|
2107
|
-
scope_rules={
|
|
2108
|
-
"or": [
|
|
2109
|
-
{
|
|
2110
|
-
"operator": "in",
|
|
2111
|
-
"path": [
|
|
2112
|
-
"contentId"
|
|
2113
|
-
],
|
|
2114
|
-
"value": [
|
|
2115
|
-
"cont_u888z7cazxxm4lugfdjq7pks"
|
|
2116
|
-
]
|
|
2117
|
-
},
|
|
2118
|
-
{
|
|
2119
|
-
"operator": "contains",
|
|
2120
|
-
"path": [
|
|
2121
|
-
"folderIdPath"
|
|
2122
|
-
],
|
|
2123
|
-
"value": "uniquepathid://scope_btfo28b3eeelwh5obwgea71bl/scope_fn56ta67knd6w4medgq3028fx"
|
|
2124
|
-
}
|
|
2125
|
-
]
|
|
2126
|
-
},
|
|
2127
|
-
stop_condition = "completedAt" # If not specified, stoppedStreamingAt will be set by default
|
|
2128
|
-
)
|
|
2129
|
-
```
|
|
2130
|
-
|
|
2131
|
-
#### `unique_sdk.utils.chat_in_space.chat_against_file`
|
|
2132
|
-
|
|
2133
|
-
The following script enables you to chat against a file.
|
|
2134
|
-
|
|
2135
|
-
You must provide the following parameters:
|
|
2136
|
-
- `assistantId`: The assistant to be used for the chat.
|
|
2137
|
-
- `path_to_file`: The local path of the file to be uploaded.
|
|
2138
|
-
- `displayed_filename`: The name of the file to be displayed.
|
|
2139
|
-
- `mime_type`: The mime type of the ifle to be uploaded.
|
|
2140
|
-
- `text`: The text to be sent to the chat for chatting against the file.
|
|
2141
|
-
|
|
2142
|
-
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. The function deletes the chat at the end unless the `should_delete_chat` is set to false.
|
|
2143
|
-
|
|
2144
|
-
**Optional parameters:**
|
|
2145
|
-
- `poll_interval`: The number of seconds to wait between polling attempts (default: `1` second).
|
|
2146
|
-
- `max_wait`: The maximum number of seconds to wait for the message to complete (default: `60` seconds).
|
|
2147
|
-
- `should_delete_chat`: Setting this flag determines whether the chat should be deleted at the end or not. Default is True.
|
|
2148
|
-
|
|
2149
|
-
Example of chatting against a PDF. (The usage can be extended to any supported file type)
|
|
2150
|
-
|
|
2151
|
-
```python
|
|
2152
|
-
latest_message = await unique_sdk.utils.chat_in_space.chat_against_file(
|
|
2153
|
-
user_id=user_id,
|
|
2154
|
-
company_id=company_id,
|
|
2155
|
-
assistant_id="assistant_hjcdga64bkcjnhu4",
|
|
2156
|
-
path_to_file="/files/hello.pdf",
|
|
2157
|
-
displayed_filename="hello.pdf",
|
|
2158
|
-
mime_type="application/pdf",
|
|
2159
|
-
text="Give me a bullet point summary of the file.",
|
|
2160
|
-
)
|
|
2161
|
-
```
|
|
2162
|
-
|
|
2163
|
-
#### `unique_sdk.utils.chat_in_space.wait_for_ingestion_completion`
|
|
2164
|
-
|
|
2165
|
-
The following script enables you to wait for the ingestion of a file. This should be used carefully as it continuously polls for the status. In case of bigger files, adjust the `poll_interval` and `max_waits`.
|
|
2166
|
-
|
|
2167
|
-
You must provide the following parameter:
|
|
2168
|
-
- `content_id`: The id of the content to check.
|
|
2169
|
-
|
|
2170
|
-
The script polls until the content ingestion is finished or the maximum wait time is reached and throws in case ingestion fails. The function assumes that the content exists.
|
|
2171
|
-
|
|
2172
|
-
**Optional parameters:**
|
|
2173
|
-
- `chat_id`: In case the content is uploaded to a chat, the `chat_id` must be provided.
|
|
2174
|
-
- `poll_interval`: The number of seconds to wait between polling attempts (default: `1` second).
|
|
2175
|
-
- `max_wait`: The maximum number of seconds to wait for the message to complete (default: `60` seconds).
|
|
2176
|
-
|
|
2177
|
-
Example of waiting for the ingestion of a file in the Knowledge Base.
|
|
2178
|
-
|
|
2179
|
-
```python
|
|
2180
|
-
await unique_sdk.utils.chat_in_space.wait_for_ingestion_completion(
|
|
2181
|
-
user_id=user_id,
|
|
2182
|
-
company_id=company_id,
|
|
2183
|
-
content_id="cont_ddlezvag4kzxudfr24lrjc5mx",
|
|
2184
|
-
)
|
|
2185
|
-
```
|
|
2186
|
-
|
|
2187
|
-
## Error Handling
|
|
2188
|
-
|
|
2189
|
-
## Examples
|
|
2190
|
-
|
|
2191
|
-
An example Flask app demonstrating the usage of each API resource and how to interact with Webhooks is available in our repository at `/examples/custom-assistant`.
|
|
2192
|
-
|
|
2193
|
-
## Credits
|
|
2194
|
-
|
|
2195
|
-
This is a _fork_ / inspired-by the fantastic Stripe Python SDK (https://github.com/stripe/stripe-python).
|
|
2196
|
-
|
|
2197
|
-
# Changelog
|
|
2198
|
-
|
|
2199
|
-
All notable changes to this project will be documented in this file.
|
|
2200
|
-
|
|
2201
|
-
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
2202
|
-
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
2203
|
-
|
|
2204
|
-
## [0.10.51] - 2025-11-21
|
|
2205
|
-
- Add function to get a space.
|
|
2206
|
-
|
|
2207
|
-
## [0.10.50] - 2025-11-21
|
|
2208
|
-
- Allow updating the configuration of a user and group.
|
|
2209
|
-
|
|
2210
|
-
## [0.10.49] - 2025-11-21
|
|
2211
|
-
- Add get folder by scope id function
|
|
2212
|
-
|
|
2213
|
-
## [0.10.48] - 2025-11-20
|
|
2214
|
-
- Update Agentic Table LogDetail and LogEntry types.
|
|
2215
|
-
|
|
2216
|
-
## [0.10.47] - 2025-11-19
|
|
2217
|
-
- Add expired/s at fields on content search result.
|
|
2218
|
-
|
|
2219
|
-
## [0.10.46] - 2025-11-18
|
|
2220
|
-
- chat_against_file function allows now a should_delete_chat flag.
|
|
2221
|
-
|
|
2222
|
-
## [0.10.45] - 2025-11-18
|
|
2223
|
-
- Create group and manage users functions.
|
|
2224
|
-
|
|
2225
|
-
## [0.10.44] - 2025-11-18
|
|
2226
|
-
- add function to get all messages in a chat.
|
|
2227
|
-
|
|
2228
|
-
## [0.10.43] - 2025-11-14
|
|
2229
|
-
- Add get, delete and update groups functions.
|
|
2230
|
-
|
|
2231
|
-
## [0.10.42] - 2025-11-14
|
|
2232
|
-
- Add get_users function.
|
|
2233
|
-
|
|
2234
|
-
## [0.10.41] - 2025-11-13
|
|
2235
|
-
- Add create_message and get_latest_message.
|
|
2236
|
-
|
|
2237
|
-
## [0.10.40] - 2025-11-10
|
|
2238
|
-
- Don't send description if not defined.
|
|
2239
|
-
|
|
2240
|
-
## [0.10.39] - 2025-11-07
|
|
2241
|
-
- Add function to get llm models
|
|
2242
|
-
|
|
2243
|
-
## [0.10.38] - 2025-11-06
|
|
2244
|
-
- Add description property to Reference and Content.
|
|
2245
|
-
|
|
2246
|
-
## [0.10.37] - 2025-11-04
|
|
2247
|
-
- Introduce local integration tests for Content API Resource
|
|
2248
|
-
|
|
2249
|
-
## [0.10.36] - 2025-11-04
|
|
2250
|
-
- Introduce local integration tests for Folder API Resource
|
|
2251
|
-
|
|
2252
|
-
## [0.10.35] - 2025-11-04
|
|
2253
|
-
- Inmprove folder get infos types.
|
|
2254
|
-
|
|
2255
|
-
## [0.10.34] - 2025-10-29
|
|
2256
|
-
- Add documentation for agentic table.
|
|
2257
|
-
|
|
2258
|
-
## [0.10.33] - 2025-10-27
|
|
2259
|
-
- Improve messagelog and message execution types.
|
|
2260
|
-
|
|
2261
|
-
## [0.10.32] - 2025-10-14
|
|
2262
|
-
- Add function to stream to chat frontend.
|
|
2263
|
-
|
|
2264
|
-
## [0.10.31] - 2025-10-13
|
|
2265
|
-
- Add readme for message log and execution.
|
|
2266
|
-
|
|
2267
|
-
## [0.10.30] - 2025-10-07
|
|
2268
|
-
- Improve types for content get infos.
|
|
2269
|
-
|
|
2270
|
-
## [0.10.29] - 2025-10-06
|
|
2271
|
-
- Switch default model used from `GPT-3.5-turbo (0125)` to `GPT-4o (1120)`
|
|
2272
|
-
|
|
2273
|
-
## [0.10.28] - 2025-10-03
|
|
2274
|
-
- Use non blocking versions of `Space.get_latest_message` and `Message.retrieve` in `send_message_and_wait_for_completion`.
|
|
2275
|
-
|
|
2276
|
-
## [0.10.27] - 2025-09-24
|
|
2277
|
-
- Improve readme to use Unique AI.
|
|
2278
|
-
|
|
2279
|
-
## [0.10.26] - 2025-09-22
|
|
2280
|
-
- Improve typing.
|
|
2281
|
-
|
|
2282
|
-
## [0.10.25] - 2025-09-18
|
|
2283
|
-
- Add support for udpate and delete files by file or folder path.
|
|
2284
|
-
|
|
2285
|
-
## [0.10.24] - 2025-09-17
|
|
2286
|
-
- Add function to update a folder.
|
|
2287
|
-
|
|
2288
|
-
## [0.10.23] - 2025-09-12
|
|
2289
|
-
- Revert to using default reasoning effort.
|
|
2290
|
-
|
|
2291
|
-
## [0.10.22] - 2025-09-12
|
|
2292
|
-
- Add support for metadata update of a file.
|
|
2293
|
-
|
|
2294
|
-
## [0.10.21] - 2025-09-04
|
|
2295
|
-
- Update Chat Completions API types and add support for reasoning effort.
|
|
2296
|
-
|
|
2297
|
-
## [0.10.20] - 2025-09-04
|
|
2298
|
-
- Update Responses API types
|
|
2299
|
-
|
|
2300
|
-
## [0.10.19] - 2025-09-02
|
|
2301
|
-
- Improve `send_message_and_wait_for_completion`:
|
|
2302
|
-
- Add option to select stop_condition `["stoppedStreamingAt", "completedAt"]`.
|
|
2303
|
-
- Load `debugInfo` from `last_user_message` for better developer experience.
|
|
2304
|
-
|
|
2305
|
-
## [0.10.18] - 2025-09-02
|
|
2306
|
-
- Temporarily remove support for update and delete files by filePath.
|
|
2307
|
-
|
|
2308
|
-
## [0.10.17] - 2025-09-01
|
|
2309
|
-
- Add function to update a file
|
|
2310
|
-
|
|
2311
|
-
## [0.10.16] - 2025-08-31
|
|
2312
|
-
- Add function to delete a content.
|
|
2313
|
-
|
|
2314
|
-
## [0.10.15] - 2025-08-28
|
|
2315
|
-
- Add default values for message log types
|
|
2316
|
-
|
|
2317
|
-
## [0.10.14] - 2025-08-28
|
|
2318
|
-
- Add function to delete folders and files recursively
|
|
2319
|
-
|
|
2320
|
-
## [0.10.13] - 2025-08-24
|
|
2321
|
-
- Add functions to create, get and update a message eecution and create and update a message log.
|
|
2322
|
-
|
|
2323
|
-
## [0.10.12] - 2025-08-24
|
|
2324
|
-
- Switch to using Content get info deprecated endpoint to make sure we support older release versions.
|
|
2325
|
-
|
|
2326
|
-
## [0.10.11] - 2025-08-24
|
|
2327
|
-
- Enforce usage of ruff using pipeline
|
|
2328
|
-
|
|
2329
|
-
## [0.10.10] - 2025-08-18
|
|
2330
|
-
- Fix wrong name of references in `Space.Message`.
|
|
2331
|
-
- Fix wrong name of assessment in `Space.Message`.
|
|
2332
|
-
- Remove default values for `text`, `originalText` and `debugInfo` in `Space.Message` as these don't have an effect.
|
|
2333
|
-
|
|
2334
|
-
## [0.10.9] - 2025-08-15
|
|
2335
|
-
- Add script to wait for content ingestion finished.
|
|
2336
|
-
|
|
2337
|
-
## [0.10.8] - 2025-08-13
|
|
2338
|
-
- Add support for Agentic Table.
|
|
2339
|
-
|
|
2340
|
-
## [0.10.7] - 2025-08-13
|
|
2341
|
-
- Make metadata optional when uploading a file.
|
|
2342
|
-
|
|
2343
|
-
## [0.10.6] - 2025-08-06
|
|
2344
|
-
- Make tools optional for running an agent.
|
|
2345
|
-
|
|
2346
|
-
## [0.10.5] - 2025-08-06
|
|
2347
|
-
- Get paginated files and folders info.
|
|
2348
|
-
|
|
2349
|
-
## [0.10.4] - 2025-08-05
|
|
2350
|
-
- Add support for reasoning API with streaming within a chat.
|
|
2351
|
-
|
|
2352
|
-
## [0.10.3] - 2025-08-05
|
|
2353
|
-
- Expose scoreThreshold param for search.
|
|
2354
|
-
|
|
2355
|
-
## [0.10.2] - 2025-08-05
|
|
2356
|
-
- Add script to chat against file.
|
|
2357
|
-
|
|
2358
|
-
## [0.10.1] - 2025-08-05
|
|
2359
|
-
- Allow deletion of a space chat.
|
|
2360
|
-
|
|
2361
|
-
## [0.10.0] - 2025-08-04
|
|
2362
|
-
- Add MCP support
|
|
2363
|
-
|
|
2364
|
-
## [0.9.42] - 2025-07-31
|
|
2365
|
-
- Fix wrong chat in space example.
|
|
2366
|
-
|
|
2367
|
-
## [0.9.41] - 2025-07-31
|
|
2368
|
-
- Fix double-slash error in open ai proxy script.
|
|
2369
|
-
|
|
2370
|
-
## [0.9.40] - 2025-07-22
|
|
2371
|
-
- Fixed bug where get requests send body with the request. This is not allowed by WAF policies.
|
|
2372
|
-
|
|
2373
|
-
## [0.9.39] - 2025-07-18
|
|
2374
|
-
- Add script to chat in a space.
|
|
2375
|
-
|
|
2376
|
-
## [0.9.38] - 2025-07-18
|
|
2377
|
-
- [Experimental] Add support for Unique OpenAI proxy. You can now use the OpenAI SDK directly through Unique. Checkout how to do this and a few examples here: `tutorials/unique_basics/sdk_examples/openai_scripts.py`.
|
|
2378
|
-
|
|
2379
|
-
## [0.9.37] - 2025-07-10
|
|
2380
|
-
- Add `sheetName` property to the `MagicTableSheetIngestParams` object used by function that ingests magic table sheets.
|
|
2381
|
-
|
|
2382
|
-
## [0.9.36] - 2025-06-23
|
|
2383
|
-
- Allow passing a user id when creating chat completions. This is optional and it does not impact the current behaviour.
|
|
2384
|
-
|
|
2385
|
-
## [0.9.35] - 2025-06-18
|
|
2386
|
-
- Allow scope access updates (add/remove) on folder based on scope id or path.
|
|
2387
|
-
|
|
2388
|
-
## [0.9.34] - 2025-06-17
|
|
2389
|
-
- Allow ingestion config updates on folder based on scope id or path.
|
|
2390
|
-
|
|
2391
|
-
## [0.9.33] - 2025-06-11
|
|
2392
|
-
- Add function to get a folder by id or by path.
|
|
2393
|
-
|
|
2394
|
-
## [0.9.32] - 2025-06-11
|
|
2395
|
-
- Add function to ingest magic table sheets.
|
|
2396
|
-
|
|
2397
|
-
## [0.9.31] - 2025-05-21
|
|
2398
|
-
- Add function to update folder access (add or remove).
|
|
2399
|
-
|
|
2400
|
-
## [0.9.30] - 2025-05-21
|
|
2401
|
-
- Add function to update folder ingestion config.
|
|
2402
|
-
|
|
2403
|
-
## [0.9.29] - 2025-05-20
|
|
2404
|
-
- Add function to create folder paths if they do not exist.
|
|
2405
|
-
|
|
2406
|
-
## [0.9.28] - 2025-05-20
|
|
2407
|
-
- Add function to search content info. This also allows filtering content info by metadata info.
|
|
2408
|
-
|
|
2409
|
-
## [0.9.27] - 2025-05-14
|
|
2410
|
-
- Add the possibility to specify metadata when creating or updating a Content.
|
|
2411
|
-
|
|
2412
|
-
## [0.9.26] - 2025-05-13
|
|
2413
|
-
- Add the possibility to specify ingestionConfig when creating or updating a Content.
|
|
2414
|
-
|
|
2415
|
-
## [0.9.25] - 2025-05-02
|
|
2416
|
-
- Fixed typos in `README.md`, including incorrect `sdk.utils` imports and code example errors.
|
|
2417
|
-
|
|
2418
|
-
## [0.9.24] - 2025-04-23
|
|
2419
|
-
- Make `chatId` property in `Search.CreateParams` optional
|
|
2420
|
-
|
|
2421
|
-
## [0.9.23] - 2025-03-25
|
|
2422
|
-
- Define programming language classifier explicitly for python 3.11
|
|
2423
|
-
|
|
2424
|
-
## [0.9.22] - 2025-02-25
|
|
2425
|
-
- update the retry_on_error to only `APIError` and `APIConnectionError` update the `resp["error"]` to be `resp.get("error")` to avoid key error
|
|
2426
|
-
|
|
2427
|
-
## [0.9.21] - 2025-02-21
|
|
2428
|
-
- Add title parameter and change labels in `MessageAssessment`
|
|
2429
|
-
|
|
2430
|
-
## [0.9.20] - 2025-02-01
|
|
2431
|
-
- Add url parameter to `MessageAssessment.create_async` and `MessageAssessment.modify_async`
|
|
2432
|
-
|
|
2433
|
-
## [0.9.19] - 2025-01-31
|
|
2434
|
-
- Add `MessageAssessment` resource
|
|
2435
|
-
|
|
2436
|
-
## [0.9.18] - 2025-01-22
|
|
2437
|
-
- Removed `Invalid response body from API` from `retry_dict` as it's our own artificail error.
|
|
2438
|
-
|
|
2439
|
-
## [0.9.17] - 2025-01-03
|
|
2440
|
-
- BREAKING CHANGE!! Removed unused `id` from `ShortTermMemory` create and find methods.
|
|
2441
|
-
|
|
2442
|
-
## [0.9.16] - 2024-12-19
|
|
2443
|
-
- Corrected return type of `Search.create` and `Search.create_async` to `List[Search]`
|
|
2444
|
-
- Retry on `Connection aborted` error
|
|
2445
|
-
|
|
2446
|
-
## [0.9.15] - 2024-12-06
|
|
2447
|
-
- Add `Internal server error` and `You can retry your request` to the retry logic
|
|
2448
|
-
|
|
2449
|
-
## [0.9.14] - 2024-12-06
|
|
2450
|
-
- Add `contentIds` to `Search.create` and `Search.create_async`
|
|
2451
|
-
|
|
2452
|
-
## [0.9.13] - 2024-10-23
|
|
2453
|
-
- Add retry for `5xx` errors, add additional error message.
|
|
2454
|
-
|
|
2455
|
-
## [0.9.12] - 2024-11-21
|
|
2456
|
-
- Include original error message in returned exceptions
|
|
2457
|
-
|
|
2458
|
-
## [0.9.11] - 2024-11-18
|
|
2459
|
-
- Add `ingestionConfig` to `UpsertParams.Input` parameters
|
|
2460
|
-
|
|
2461
|
-
## [0.9.10] - 2024-10-23
|
|
2462
|
-
- Remove `temperature` parameter from `Integrated.chat_stream_completion`, `Integrated.chat_stream_completion_async`, `ChatCompletion.create` and `ChatCompletion.create_async` methods. To use `temperature` parameter, set the attribute in `options` parameter instead.
|
|
2463
|
-
|
|
2464
|
-
## [0.9.9] - 2024-10-23
|
|
2465
|
-
- Revert deletion of `Message.retrieve` method
|
|
2466
|
-
|
|
2467
|
-
## [0.9.8] - 2024-10-16
|
|
2468
|
-
- Add `retries` for `_static_request` and `_static_request_async` in `APIResource` - When the error messages contains either `"problem proxying the request"`,
|
|
2469
|
-
or `"Upstream service reached a hard timeout"`,
|
|
2470
|
-
## [0.9.7] - 2024-09-23
|
|
2471
|
-
- Add `completedAt` to `CreateParams` of `Message`
|
|
2472
|
-
|
|
2473
|
-
## [0.9.6] - 2024-09-03
|
|
2474
|
-
- Added `metaDataFilter` to `Search` parameters.
|
|
2475
|
-
|
|
2476
|
-
## [0.9.5] - 2024-08-07
|
|
2477
|
-
- Add `completedAt` to `ModifyParams`
|
|
2478
|
-
|
|
2479
|
-
## [0.9.4] - 2024-07-31
|
|
2480
|
-
- Add `close` and `close_async` to `http_client`
|
|
2481
|
-
- Make `httpx` the default client for async requests
|
|
2482
|
-
|
|
2483
|
-
## [0.9.3] - 2024-07-31
|
|
2484
|
-
- `Search.create`, `Message`, `ChatCompletion` parameters that were marked `NotRequired` are now also `Optional`
|
|
2485
|
-
|
|
2486
|
-
## [0.9.2] - 2024-07-30
|
|
2487
|
-
- Bug fix in `Search.create`: langugage -> language
|
|
2488
|
-
|
|
2489
|
-
## [0.9.1] - 2024-07-30
|
|
2490
|
-
- Added parameters to `Search.create` and `Search.create_async`
|
|
2491
|
-
- `language` for full text search
|
|
2492
|
-
- `reranker` to reranker search results
|
|
2493
|
-
|
|
2494
|
-
## [0.9.0] - 2024-07-29
|
|
2495
|
-
- Added the possibility to make async requests to the unique APIs using either aiohttp or httpx as client
|
|
2496
|
-
|