superwise-api 4.16.0__tar.gz → 4.17.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {superwise_api-4.16.0 → superwise_api-4.17.0}/PKG-INFO +2 -1
- {superwise_api-4.16.0 → superwise_api-4.17.0}/pyproject.toml +2 -1
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/api_client.py +25 -11
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/rest.py +26 -12
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/agent.py +139 -17
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/dataset.py +55 -1
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/destination.py +47 -7
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/agent/agent.py +34 -0
- superwise_api-4.17.0/superwise_api/models/agent/feedback.py +16 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/agent/playground.py +3 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset/dataset.py +4 -0
- superwise_api-4.17.0/superwise_api/models/destination/destination.py +82 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/integration/integration.py +2 -0
- superwise_api-4.16.0/superwise_api/models/agent/feedback.py +0 -41
- superwise_api-4.16.0/superwise_api/models/destination/destination.py +0 -37
- {superwise_api-4.16.0 → superwise_api-4.17.0}/README.md +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/api_response.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/configuration.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/exceptions.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/models/page.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/models/threshold_settings.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/config.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/base.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/dashboard.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/dashboard_item.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/dataset_source.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/guardrails.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/integration.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/knowledge.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/mcp.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/model.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/model_provider.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/policy.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/source.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/entities/tag.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/errors.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/agent/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/agent/flowise.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/context/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/context/context.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dashboard/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dashboard/dashboard.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dashboard/query.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dashboard_item/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dashboard_item/dashboard_item.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset/dataset_schema.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset_source/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset_source/dataset_source.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/destination/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/guardrails/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/guardrails/guardrails.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/integration/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/knowledge/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/knowledge/knowledge.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/mcp/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/mcp/mcp.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/model/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/model/model.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/model_provider/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/model_provider/model_provider.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/policy/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/policy/policy.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/policy/query.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/source/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/source/source.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/tag/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/tag/tag.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/tool/__init__.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/tool/tool.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/utils.py +0 -0
- {superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/superwise_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: superwise-api
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.17.0
|
|
4
4
|
Summary: Superwise SDK for Python
|
|
5
5
|
License: MIT
|
|
6
6
|
Keywords: OpenAPI,SuperwiseSDK
|
|
@@ -14,6 +14,7 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.13
|
|
15
15
|
Requires-Dist: Pillow (>=10.0.0,<11.0.0)
|
|
16
16
|
Requires-Dist: aenum (>=3.1.11)
|
|
17
|
+
Requires-Dist: jsonschema (>=4.26.0,<5.0.0)
|
|
17
18
|
Requires-Dist: pydantic (>=2.10.4,<3.0.0)
|
|
18
19
|
Requires-Dist: pydantic-settings (>=2.7.0,<3.0.0)
|
|
19
20
|
Requires-Dist: python-dateutil (>=2.8.2)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
packages = [{ include = "superwise_api", from = "." }]
|
|
3
|
-
version = "4.
|
|
3
|
+
version = "4.17.0"
|
|
4
4
|
include = ["superwise_api/client/py.typed"]
|
|
5
5
|
|
|
6
6
|
[tool.poetry.dependencies]
|
|
@@ -11,6 +11,7 @@ aenum = ">=3.1.11"
|
|
|
11
11
|
requests = "^2.32.0"
|
|
12
12
|
pydantic-settings = "^2.7.0"
|
|
13
13
|
Pillow = "^10.0.0"
|
|
14
|
+
jsonschema = "^4.26.0"
|
|
14
15
|
|
|
15
16
|
|
|
16
17
|
[tool.poetry.group.dev.dependencies]
|
|
@@ -7,7 +7,7 @@ import re
|
|
|
7
7
|
import tempfile
|
|
8
8
|
import uuid
|
|
9
9
|
from multiprocessing.pool import ThreadPool
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
from urllib.parse import quote
|
|
12
12
|
|
|
13
13
|
from dateutil.parser import parse
|
|
@@ -774,7 +774,7 @@ class ApiClient:
|
|
|
774
774
|
**kwargs,
|
|
775
775
|
)
|
|
776
776
|
|
|
777
|
-
def put(self, resource_path: str, data:
|
|
777
|
+
def put(self, resource_path: str, data: dict | None = None, **kwargs) -> BaseModel:
|
|
778
778
|
_params = locals()
|
|
779
779
|
|
|
780
780
|
_all_params = ["async_req", "_request_auth", "_content_type", "_headers", "response_types_map"]
|
|
@@ -860,11 +860,19 @@ class ApiClient:
|
|
|
860
860
|
)
|
|
861
861
|
|
|
862
862
|
def post(
|
|
863
|
-
self, resource_path: str, data:
|
|
863
|
+
self, resource_path: str, data: dict | None = None, query_params: dict | None = None, **kwargs
|
|
864
864
|
) -> BaseModel:
|
|
865
865
|
_params = locals()
|
|
866
866
|
|
|
867
|
-
_all_params = [
|
|
867
|
+
_all_params = [
|
|
868
|
+
"files",
|
|
869
|
+
"async_req",
|
|
870
|
+
"_request_auth",
|
|
871
|
+
"_content_type",
|
|
872
|
+
"_headers",
|
|
873
|
+
"response_types_map",
|
|
874
|
+
"post_params",
|
|
875
|
+
]
|
|
868
876
|
if "model_name" in kwargs:
|
|
869
877
|
_all_params.append("model_name")
|
|
870
878
|
|
|
@@ -884,18 +892,21 @@ class ApiClient:
|
|
|
884
892
|
# process the header parameters
|
|
885
893
|
_header_params = dict(_params.get("_headers", {}))
|
|
886
894
|
# process the form parameters
|
|
887
|
-
_form_params = []
|
|
895
|
+
_form_params = _params.get("post_params", [])
|
|
888
896
|
_files = kwargs.get("files", {})
|
|
889
897
|
# process the body parameter
|
|
890
898
|
_body_params = None
|
|
891
|
-
if data is not None:
|
|
899
|
+
if data is not None and not _form_params:
|
|
892
900
|
_body_params = data
|
|
893
901
|
|
|
894
902
|
# set the HTTP header `Accept`
|
|
895
903
|
_header_params["Accept"] = self.select_header_accept(["application/json"])
|
|
896
904
|
|
|
897
905
|
# set the HTTP header `Content-Type`
|
|
898
|
-
|
|
906
|
+
if _form_params:
|
|
907
|
+
_content_types_list = "multipart/form-data"
|
|
908
|
+
else:
|
|
909
|
+
_content_types_list = _params.get("_content_type", self.select_header_content_type(["application/json"]))
|
|
899
910
|
if _content_types_list:
|
|
900
911
|
_header_params["Content-Type"] = _content_types_list
|
|
901
912
|
|
|
@@ -924,7 +935,7 @@ class ApiClient:
|
|
|
924
935
|
)
|
|
925
936
|
|
|
926
937
|
def delete(
|
|
927
|
-
self, resource_path: str, model_name: str, entity_id: str, query_params:
|
|
938
|
+
self, resource_path: str, model_name: str, entity_id: str, query_params: dict | None = None, **kwargs
|
|
928
939
|
) -> BaseModel:
|
|
929
940
|
_params = locals()
|
|
930
941
|
|
|
@@ -1151,14 +1162,16 @@ class ApiClient:
|
|
|
1151
1162
|
self,
|
|
1152
1163
|
resource_path: str,
|
|
1153
1164
|
response_model,
|
|
1154
|
-
data:
|
|
1165
|
+
data: dict | None = None,
|
|
1166
|
+
post_params: list | None = None,
|
|
1155
1167
|
**kwargs,
|
|
1156
1168
|
):
|
|
1157
1169
|
"""Performs a streaming POST request and yields parsed response objects.
|
|
1158
1170
|
|
|
1159
1171
|
:param resource_path: Path to method endpoint.
|
|
1160
1172
|
:param response_model: Model class to deserialize each line to.
|
|
1161
|
-
:param data: Request body data.
|
|
1173
|
+
:param data: Request body data (JSON).
|
|
1174
|
+
:param post_params: Multipart form-data fields (list of tuples). Mutually exclusive with data.
|
|
1162
1175
|
:param kwargs: Additional arguments (_headers, _request_timeout, _request_auth).
|
|
1163
1176
|
:yields: Parsed response_model instances.
|
|
1164
1177
|
:raises StreamingError: If an error event is received in the stream.
|
|
@@ -1175,7 +1188,7 @@ class ApiClient:
|
|
|
1175
1188
|
|
|
1176
1189
|
# Set content type and accept headers
|
|
1177
1190
|
_header_params["Accept"] = "application/x-ndjson"
|
|
1178
|
-
_header_params["Content-Type"] = "application/json"
|
|
1191
|
+
_header_params["Content-Type"] = "multipart/form-data" if post_params else "application/json"
|
|
1179
1192
|
|
|
1180
1193
|
# Handle authentication
|
|
1181
1194
|
_request_auth = _params.get("_request_auth")
|
|
@@ -1196,6 +1209,7 @@ class ApiClient:
|
|
|
1196
1209
|
url,
|
|
1197
1210
|
headers=_header_params,
|
|
1198
1211
|
body=data,
|
|
1212
|
+
post_params=post_params,
|
|
1199
1213
|
_request_timeout=_params.get("_request_timeout"),
|
|
1200
1214
|
)
|
|
1201
1215
|
|
|
@@ -404,6 +404,7 @@ class RESTClientObject:
|
|
|
404
404
|
url,
|
|
405
405
|
headers=None,
|
|
406
406
|
body=None,
|
|
407
|
+
post_params=None,
|
|
407
408
|
_request_timeout=None,
|
|
408
409
|
):
|
|
409
410
|
"""Perform a streaming POST request.
|
|
@@ -411,6 +412,7 @@ class RESTClientObject:
|
|
|
411
412
|
:param url: http request url
|
|
412
413
|
:param headers: http request headers
|
|
413
414
|
:param body: request json body
|
|
415
|
+
:param post_params: multipart/form-data fields (list of tuples)
|
|
414
416
|
:param _request_timeout: timeout setting for this request
|
|
415
417
|
:return: StreamingRESTResponse object for iterating over lines
|
|
416
418
|
"""
|
|
@@ -424,18 +426,30 @@ class RESTClientObject:
|
|
|
424
426
|
timeout = urllib3.Timeout(connect=_request_timeout[0], read=_request_timeout[1])
|
|
425
427
|
|
|
426
428
|
try:
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
429
|
+
if post_params:
|
|
430
|
+
# Remove Content-Type so urllib3 sets it with the multipart boundary
|
|
431
|
+
headers = {k: v for k, v in headers.items() if k != "Content-Type"}
|
|
432
|
+
r = self.pool_manager.request(
|
|
433
|
+
"POST",
|
|
434
|
+
url,
|
|
435
|
+
fields=post_params,
|
|
436
|
+
encode_multipart=True,
|
|
437
|
+
preload_content=False,
|
|
438
|
+
timeout=timeout,
|
|
439
|
+
headers=headers,
|
|
440
|
+
)
|
|
441
|
+
else:
|
|
442
|
+
request_body = None
|
|
443
|
+
if body is not None:
|
|
444
|
+
request_body = json.dumps(body)
|
|
445
|
+
r = self.pool_manager.request(
|
|
446
|
+
"POST",
|
|
447
|
+
url,
|
|
448
|
+
body=request_body,
|
|
449
|
+
preload_content=False,
|
|
450
|
+
timeout=timeout,
|
|
451
|
+
headers=headers,
|
|
452
|
+
)
|
|
439
453
|
except urllib3.exceptions.SSLError as e:
|
|
440
454
|
msg = "{0}\n{1}".format(type(e).__name__, str(e))
|
|
441
455
|
raise ApiException(status=0, reason=msg)
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import io
|
|
2
|
+
import json
|
|
1
3
|
from typing import Iterator
|
|
2
|
-
|
|
4
|
+
|
|
3
5
|
from typing import Sequence
|
|
4
6
|
|
|
7
|
+
from PIL import Image
|
|
5
8
|
from pydantic import conint
|
|
6
9
|
|
|
7
10
|
from superwise_api.client.api_client import ApiClient
|
|
@@ -42,6 +45,42 @@ class AgentApi(CoreEntitiyApi):
|
|
|
42
45
|
super().__init__(api_client)
|
|
43
46
|
self._playground_resource_path = "/v1/application-playground"
|
|
44
47
|
|
|
48
|
+
def _detect_image_type(self, image_bytes: bytes) -> tuple[str, str]:
|
|
49
|
+
try:
|
|
50
|
+
with Image.open(io.BytesIO(image_bytes)) as img:
|
|
51
|
+
format_name = img.format
|
|
52
|
+
if format_name is None:
|
|
53
|
+
raise ValueError("Could not detect image format")
|
|
54
|
+
format_map = {
|
|
55
|
+
"JPEG": ("image/jpeg", "jpg"),
|
|
56
|
+
"PNG": ("image/png", "png"),
|
|
57
|
+
"WEBP": ("image/webp", "webp"),
|
|
58
|
+
}
|
|
59
|
+
if format_name in format_map:
|
|
60
|
+
return format_map[format_name]
|
|
61
|
+
raise ValueError(f"Unsupported image format: {format_name}. Supported formats: JPEG, PNG, WEBP")
|
|
62
|
+
except ValueError:
|
|
63
|
+
raise
|
|
64
|
+
except Exception:
|
|
65
|
+
raise ValueError("Image type not allowed. Only PNG, JPEG, and WebP are supported.")
|
|
66
|
+
|
|
67
|
+
def _validate_images(self, images: list[bytes]) -> None:
|
|
68
|
+
if len(images) > 3:
|
|
69
|
+
raise ValueError(f"Maximum 3 images allowed, got {len(images)}")
|
|
70
|
+
for idx, img in enumerate(images):
|
|
71
|
+
if not isinstance(img, bytes):
|
|
72
|
+
raise ValueError(f"Image at index {idx} must be bytes, got {type(img)}")
|
|
73
|
+
if len(img) > 20 * 1024 * 1024:
|
|
74
|
+
raise ValueError(f"Image at index {idx} exceeds the 20MB size limit")
|
|
75
|
+
self._detect_image_type(img)
|
|
76
|
+
|
|
77
|
+
def _build_image_fields(self, images: list[bytes]) -> list[tuple]:
|
|
78
|
+
fields = []
|
|
79
|
+
for i, img in enumerate(images):
|
|
80
|
+
media_type, ext = self._detect_image_type(img)
|
|
81
|
+
fields.append(("images", (f"image{i}.{ext}", img, media_type)))
|
|
82
|
+
return fields
|
|
83
|
+
|
|
45
84
|
def create(
|
|
46
85
|
self,
|
|
47
86
|
name: str,
|
|
@@ -228,7 +267,7 @@ class AgentApi(CoreEntitiyApi):
|
|
|
228
267
|
)
|
|
229
268
|
|
|
230
269
|
def get_versions(
|
|
231
|
-
self, agent_id: str, name:
|
|
270
|
+
self, agent_id: str, name: str | None = None, created_by: str | None = None, **kwargs
|
|
232
271
|
) -> list[Version]:
|
|
233
272
|
"""
|
|
234
273
|
Retrieves agent entities.
|
|
@@ -260,12 +299,12 @@ class AgentApi(CoreEntitiyApi):
|
|
|
260
299
|
|
|
261
300
|
def get(
|
|
262
301
|
self,
|
|
263
|
-
name:
|
|
264
|
-
created_by:
|
|
265
|
-
prompt:
|
|
266
|
-
dataset_id:
|
|
267
|
-
page:
|
|
268
|
-
size:
|
|
302
|
+
name: str | None = None,
|
|
303
|
+
created_by: str | None = None,
|
|
304
|
+
prompt: str | None = None,
|
|
305
|
+
dataset_id: str | None = None,
|
|
306
|
+
page: conint(strict=True, ge=1) | None = None,
|
|
307
|
+
size: conint(strict=True, le=500, ge=1) | None = None,
|
|
269
308
|
**kwargs,
|
|
270
309
|
) -> Page:
|
|
271
310
|
"""
|
|
@@ -337,7 +376,12 @@ class AgentApi(CoreEntitiyApi):
|
|
|
337
376
|
|
|
338
377
|
@BaseApi.raise_exception
|
|
339
378
|
def ask_playground(
|
|
340
|
-
self,
|
|
379
|
+
self,
|
|
380
|
+
input: str,
|
|
381
|
+
agent_config: AgentConfig,
|
|
382
|
+
chat_history: Sequence[dict] | None = None,
|
|
383
|
+
images: list[bytes] | None = None,
|
|
384
|
+
**kwargs,
|
|
341
385
|
) -> AskResponsePayload:
|
|
342
386
|
"""
|
|
343
387
|
Performs ask request in playground mode.
|
|
@@ -346,16 +390,31 @@ class AgentApi(CoreEntitiyApi):
|
|
|
346
390
|
input (str): The input to the model.
|
|
347
391
|
agent_config (AgentConfig): The type of the agent and connected tools/context.
|
|
348
392
|
chat_history (Sequence[dict], optional): The chat history.
|
|
393
|
+
images (list[bytes], optional): Up to 3 images (PNG, JPEG, WEBP, max 20MB each).
|
|
349
394
|
|
|
350
395
|
Returns:
|
|
351
396
|
AskResponsePayload: The response payload.
|
|
352
397
|
"""
|
|
398
|
+
response_types_map = {"200": AskResponsePayload, "422": "HTTPValidationError"}
|
|
399
|
+
if images:
|
|
400
|
+
self._validate_images(images)
|
|
401
|
+
fields = [
|
|
402
|
+
("input", input),
|
|
403
|
+
("chat_history", json.dumps(chat_history or [])),
|
|
404
|
+
("config", agent_config.model_dump_json(by_alias=True)),
|
|
405
|
+
]
|
|
406
|
+
fields.extend(self._build_image_fields(images))
|
|
407
|
+
return self.api_client.post(
|
|
408
|
+
resource_path=self._playground_resource_path + "/ask",
|
|
409
|
+
post_params=fields,
|
|
410
|
+
response_types_map=response_types_map,
|
|
411
|
+
**kwargs,
|
|
412
|
+
)
|
|
353
413
|
payload = {
|
|
354
414
|
"config": agent_config,
|
|
355
415
|
"input": input,
|
|
356
416
|
"chat_history": chat_history or [],
|
|
357
417
|
}
|
|
358
|
-
response_types_map = {"200": AskResponsePayload, "422": "HTTPValidationError"}
|
|
359
418
|
return self.api_client.post(
|
|
360
419
|
resource_path=self._playground_resource_path + "/ask",
|
|
361
420
|
data=payload,
|
|
@@ -369,9 +428,10 @@ class AgentApi(CoreEntitiyApi):
|
|
|
369
428
|
agent_id: str,
|
|
370
429
|
input: str,
|
|
371
430
|
api_token: str | None = None,
|
|
372
|
-
chat_history:
|
|
431
|
+
chat_history: Sequence[dict] | None = None,
|
|
373
432
|
context_id: str | None = None,
|
|
374
433
|
metadata: dict | None = None,
|
|
434
|
+
images: list[bytes] | None = None,
|
|
375
435
|
**kwargs,
|
|
376
436
|
) -> AskResponsePayload:
|
|
377
437
|
"""
|
|
@@ -382,13 +442,35 @@ class AgentApi(CoreEntitiyApi):
|
|
|
382
442
|
input (str): The input to the model.
|
|
383
443
|
api_token (str): The API token of the agent.
|
|
384
444
|
chat_history (Sequence[dict], optional): The chat history.
|
|
445
|
+
context_id (str, optional): The context ID for the conversation.
|
|
446
|
+
metadata (dict, optional): Additional metadata.
|
|
447
|
+
images (list[bytes], optional): Up to 3 images (PNG, JPEG, WEBP, max 20MB each).
|
|
385
448
|
|
|
386
449
|
Returns:
|
|
387
450
|
AskResponsePayload: The response payload.
|
|
388
451
|
"""
|
|
389
|
-
payload = {"input": input, "chat_history": chat_history or [], "context_id": context_id, "metadata": metadata}
|
|
390
|
-
headers = {"x-api-token": api_token} if api_token else {}
|
|
391
452
|
response_types_map = {"200": AskResponsePayload, "422": "HTTPValidationError"}
|
|
453
|
+
if images:
|
|
454
|
+
self._validate_images(images)
|
|
455
|
+
headers = {"x-api-token": api_token} if api_token else {}
|
|
456
|
+
if images:
|
|
457
|
+
fields = [
|
|
458
|
+
("input", input),
|
|
459
|
+
("chat_history", json.dumps(chat_history or [])),
|
|
460
|
+
]
|
|
461
|
+
if context_id is not None:
|
|
462
|
+
fields.append(("context_id", context_id))
|
|
463
|
+
if metadata is not None:
|
|
464
|
+
fields.append(("metadata", json.dumps(metadata)))
|
|
465
|
+
fields.extend(self._build_image_fields(images))
|
|
466
|
+
return self.api_client.post(
|
|
467
|
+
resource_path=f"/v1/app-worker/{agent_id}/v1/ask",
|
|
468
|
+
post_params=fields,
|
|
469
|
+
response_types_map=response_types_map,
|
|
470
|
+
_headers=headers,
|
|
471
|
+
**kwargs,
|
|
472
|
+
)
|
|
473
|
+
payload = {"input": input, "chat_history": chat_history or [], "context_id": context_id, "metadata": metadata}
|
|
392
474
|
return self.api_client.post(
|
|
393
475
|
resource_path=f"/v1/app-worker/{agent_id}/v1/ask",
|
|
394
476
|
data=payload,
|
|
@@ -401,8 +483,9 @@ class AgentApi(CoreEntitiyApi):
|
|
|
401
483
|
self,
|
|
402
484
|
input: str,
|
|
403
485
|
agent_config: AgentConfig,
|
|
404
|
-
chat_history:
|
|
405
|
-
guardrails:
|
|
486
|
+
chat_history: Sequence[dict] | None = None,
|
|
487
|
+
guardrails: list[str] | None = None,
|
|
488
|
+
images: list[bytes] | None = None,
|
|
406
489
|
**kwargs,
|
|
407
490
|
) -> Iterator[StreamedResponse]:
|
|
408
491
|
"""
|
|
@@ -413,6 +496,7 @@ class AgentApi(CoreEntitiyApi):
|
|
|
413
496
|
agent_config (AgentConfig): The type of the agent and connected tools/context.
|
|
414
497
|
chat_history (Sequence[dict], optional): The chat history.
|
|
415
498
|
guardrails (list[str], optional): List of guardrail IDs to apply.
|
|
499
|
+
images (list[bytes], optional): Up to 3 images (PNG, JPEG, WEBP, max 20MB each).
|
|
416
500
|
|
|
417
501
|
Yields:
|
|
418
502
|
StreamedResponse: Individual streaming events (system, guardrails, llm, tool, response).
|
|
@@ -420,6 +504,23 @@ class AgentApi(CoreEntitiyApi):
|
|
|
420
504
|
Raises:
|
|
421
505
|
StreamingError: If an error event is received in the stream.
|
|
422
506
|
"""
|
|
507
|
+
if images:
|
|
508
|
+
self._validate_images(images)
|
|
509
|
+
if images:
|
|
510
|
+
fields = [
|
|
511
|
+
("input", input),
|
|
512
|
+
("chat_history", json.dumps(chat_history or [])),
|
|
513
|
+
("config", agent_config.model_dump_json(by_alias=True)),
|
|
514
|
+
]
|
|
515
|
+
if guardrails:
|
|
516
|
+
fields.append(("guardrails", json.dumps(guardrails)))
|
|
517
|
+
fields.extend(self._build_image_fields(images))
|
|
518
|
+
return self.api_client.post_stream(
|
|
519
|
+
resource_path=self._playground_resource_path + "/ask/stream",
|
|
520
|
+
response_model=StreamedResponse,
|
|
521
|
+
post_params=fields,
|
|
522
|
+
**kwargs,
|
|
523
|
+
)
|
|
423
524
|
payload = {
|
|
424
525
|
"config": agent_config,
|
|
425
526
|
"input": input,
|
|
@@ -439,9 +540,10 @@ class AgentApi(CoreEntitiyApi):
|
|
|
439
540
|
agent_id: str,
|
|
440
541
|
input: str,
|
|
441
542
|
api_token: str | None = None,
|
|
442
|
-
chat_history:
|
|
543
|
+
chat_history: Sequence[dict] | None = None,
|
|
443
544
|
context_id: str | None = None,
|
|
444
545
|
metadata: dict | None = None,
|
|
546
|
+
images: list[bytes] | None = None,
|
|
445
547
|
**kwargs,
|
|
446
548
|
) -> Iterator[StreamedResponse]:
|
|
447
549
|
"""
|
|
@@ -454,6 +556,7 @@ class AgentApi(CoreEntitiyApi):
|
|
|
454
556
|
chat_history (Sequence[dict], optional): The chat history.
|
|
455
557
|
context_id (str, optional): The context ID for the conversation.
|
|
456
558
|
metadata (dict, optional): Additional metadata.
|
|
559
|
+
images (list[bytes], optional): Up to 3 images (PNG, JPEG, WEBP, max 20MB each).
|
|
457
560
|
|
|
458
561
|
Yields:
|
|
459
562
|
StreamedResponse: Individual streaming events (system, guardrails, llm, tool, response).
|
|
@@ -461,8 +564,27 @@ class AgentApi(CoreEntitiyApi):
|
|
|
461
564
|
Raises:
|
|
462
565
|
StreamingError: If an error event is received in the stream.
|
|
463
566
|
"""
|
|
464
|
-
|
|
567
|
+
if images:
|
|
568
|
+
self._validate_images(images)
|
|
465
569
|
headers = {"x-api-token": api_token} if api_token else {}
|
|
570
|
+
if images:
|
|
571
|
+
fields = [
|
|
572
|
+
("input", input),
|
|
573
|
+
("chat_history", json.dumps(chat_history or [])),
|
|
574
|
+
]
|
|
575
|
+
if context_id is not None:
|
|
576
|
+
fields.append(("context_id", context_id))
|
|
577
|
+
if metadata is not None:
|
|
578
|
+
fields.append(("metadata", json.dumps(metadata)))
|
|
579
|
+
fields.extend(self._build_image_fields(images))
|
|
580
|
+
return self.api_client.post_stream(
|
|
581
|
+
resource_path=f"/v1/app-worker/{agent_id}/v1/ask/stream",
|
|
582
|
+
response_model=StreamedResponse,
|
|
583
|
+
post_params=fields,
|
|
584
|
+
_headers=headers,
|
|
585
|
+
**kwargs,
|
|
586
|
+
)
|
|
587
|
+
payload = {"input": input, "chat_history": chat_history or [], "context_id": context_id, "metadata": metadata}
|
|
466
588
|
return self.api_client.post_stream(
|
|
467
589
|
resource_path=f"/v1/app-worker/{agent_id}/v1/ask/stream",
|
|
468
590
|
response_model=StreamedResponse,
|
|
@@ -5,7 +5,7 @@ from pydantic import conint
|
|
|
5
5
|
|
|
6
6
|
from superwise_api.client.models.page import Page
|
|
7
7
|
from superwise_api.entities.base import BaseApi, CoreEntitiyApi
|
|
8
|
-
from superwise_api.models.dataset.dataset import Dataset, SqlQueryResponse
|
|
8
|
+
from superwise_api.models.dataset.dataset import Dataset, NaturalLanguageQueryResponse, SqlQueryResponse
|
|
9
9
|
from superwise_api.models.dataset.dataset_schema import RecordLogMessage
|
|
10
10
|
from superwise_api.models.dataset_source.dataset_source import DatasetSource
|
|
11
11
|
from superwise_api.models.dataset_source.dataset_source import IngestType
|
|
@@ -288,6 +288,14 @@ class DatasetApi(CoreEntitiyApi):
|
|
|
288
288
|
_preload_content=True,
|
|
289
289
|
)
|
|
290
290
|
|
|
291
|
+
def update_record_in_dataset(self, dataset_id: str, key_field: str, key_value: str, record: dict, **kwargs):
|
|
292
|
+
"""Update a record via ``POST /{dataset_id}/update`` (async; waits for row then publishes)."""
|
|
293
|
+
return self.api_client.post(
|
|
294
|
+
resource_path=f"{self._resource_path}/{dataset_id}/update",
|
|
295
|
+
data={"key_field": key_field, "key_value": key_value, "record": record},
|
|
296
|
+
**kwargs,
|
|
297
|
+
)
|
|
298
|
+
|
|
291
299
|
def get_media(self, dataset_id: str, image_id: str, thumbnail: bool = False, **kwargs) -> tuple[str, bytes]:
|
|
292
300
|
"""Retrieve a single image from a dataset.
|
|
293
301
|
|
|
@@ -353,3 +361,49 @@ class DatasetApi(CoreEntitiyApi):
|
|
|
353
361
|
response_types_map=response_types_map,
|
|
354
362
|
**kwargs,
|
|
355
363
|
)
|
|
364
|
+
|
|
365
|
+
def execute_nl_query(self, query: str, dataset_ids: list[str], **kwargs) -> NaturalLanguageQueryResponse:
|
|
366
|
+
"""
|
|
367
|
+
Convert a natural language request to SQL and execute it.
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
query (str): Plain English description of the data you want.
|
|
371
|
+
dataset_ids (list[str]): Dataset IDs to scope the query.
|
|
372
|
+
**kwargs: Arbitrary keyword arguments passed to the API client.
|
|
373
|
+
|
|
374
|
+
Returns:
|
|
375
|
+
NaturalLanguageQueryResponse: Contains the generated SQL, a valid flag,
|
|
376
|
+
optional error message, and query data.
|
|
377
|
+
"""
|
|
378
|
+
return self._post_nl_query(query=query, dataset_ids=dataset_ids, generate_only=False, **kwargs)
|
|
379
|
+
|
|
380
|
+
def generate_nl_query(self, query: str, dataset_ids: list[str], **kwargs) -> NaturalLanguageQueryResponse:
|
|
381
|
+
"""
|
|
382
|
+
Convert a natural language request to SQL without executing it.
|
|
383
|
+
|
|
384
|
+
Args:
|
|
385
|
+
query (str): Plain English description of the data you want.
|
|
386
|
+
dataset_ids (list[str]): Dataset IDs to scope the query.
|
|
387
|
+
**kwargs: Arbitrary keyword arguments passed to the API client.
|
|
388
|
+
|
|
389
|
+
Returns:
|
|
390
|
+
NaturalLanguageQueryResponse: Contains the generated SQL and a valid flag.
|
|
391
|
+
Data is always None.
|
|
392
|
+
"""
|
|
393
|
+
return self._post_nl_query(query=query, dataset_ids=dataset_ids, generate_only=True, **kwargs)
|
|
394
|
+
|
|
395
|
+
def _post_nl_query(
|
|
396
|
+
self, query: str, dataset_ids: list[str], generate_only: bool, **kwargs
|
|
397
|
+
) -> NaturalLanguageQueryResponse:
|
|
398
|
+
response_types_map = {
|
|
399
|
+
"200": NaturalLanguageQueryResponse,
|
|
400
|
+
"400": None,
|
|
401
|
+
"422": None,
|
|
402
|
+
"500": None,
|
|
403
|
+
}
|
|
404
|
+
return self.api_client.post(
|
|
405
|
+
resource_path=self._resource_path + "/nl-query",
|
|
406
|
+
data={"query": query, "dataset_ids": dataset_ids, "generate_only": generate_only},
|
|
407
|
+
response_types_map=response_types_map,
|
|
408
|
+
**kwargs,
|
|
409
|
+
)
|
|
@@ -2,7 +2,14 @@ from typing import Optional
|
|
|
2
2
|
|
|
3
3
|
from superwise_api.client.models.page import Page
|
|
4
4
|
from superwise_api.entities.base import BaseApi
|
|
5
|
-
from superwise_api.models.destination.destination import
|
|
5
|
+
from superwise_api.models.destination.destination import (
|
|
6
|
+
Destination,
|
|
7
|
+
TeamsDestinationTestRequest,
|
|
8
|
+
SlackDestinationTestRequest,
|
|
9
|
+
EmailDestinationTestRequest,
|
|
10
|
+
DestinationParams,
|
|
11
|
+
DestinationType,
|
|
12
|
+
)
|
|
6
13
|
|
|
7
14
|
|
|
8
15
|
class DestinationApi(BaseApi):
|
|
@@ -43,20 +50,34 @@ class DestinationApi(BaseApi):
|
|
|
43
50
|
"""
|
|
44
51
|
return super().delete(_id=destination_id, **kwargs)
|
|
45
52
|
|
|
46
|
-
def create(
|
|
53
|
+
def create(
|
|
54
|
+
self,
|
|
55
|
+
name: str,
|
|
56
|
+
integration_type: DestinationType,
|
|
57
|
+
params: DestinationParams,
|
|
58
|
+
integration_id: str | None = None,
|
|
59
|
+
**kwargs,
|
|
60
|
+
) -> Destination:
|
|
47
61
|
"""
|
|
48
62
|
Creates a new destination.
|
|
49
63
|
|
|
50
64
|
Args:
|
|
51
65
|
name (str): The name of the destination.
|
|
52
|
-
|
|
53
|
-
params (
|
|
66
|
+
integration_type (str): The type of the integration.
|
|
67
|
+
params (DestinationParams): The parameters of the destination.
|
|
68
|
+
integration_id (str | None): The id of the integration. Required for Slack destinations.
|
|
54
69
|
**kwargs: Arbitrary keyword arguments.
|
|
55
70
|
|
|
56
71
|
Returns:
|
|
57
72
|
Destination: The created destination.
|
|
58
73
|
"""
|
|
59
|
-
data = {
|
|
74
|
+
data = {
|
|
75
|
+
k: v
|
|
76
|
+
for k, v in dict(
|
|
77
|
+
name=name, integration_id=integration_id, integration_type=integration_type, params=params
|
|
78
|
+
).items()
|
|
79
|
+
if v is not None
|
|
80
|
+
}
|
|
60
81
|
return self.api_client.create(
|
|
61
82
|
resource_path=self._resource_path, model_class=Destination, model_name=self._model_name, data=data, **kwargs
|
|
62
83
|
)
|
|
@@ -106,14 +127,33 @@ class DestinationApi(BaseApi):
|
|
|
106
127
|
**kwargs,
|
|
107
128
|
)
|
|
108
129
|
|
|
130
|
+
def test_connection(
|
|
131
|
+
self,
|
|
132
|
+
request: TeamsDestinationTestRequest | SlackDestinationTestRequest | EmailDestinationTestRequest,
|
|
133
|
+
**kwargs,
|
|
134
|
+
) -> None:
|
|
135
|
+
"""
|
|
136
|
+
Test a webhook connection by sending a test notification.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
request (TeamsDestinationTestRequest | SlackDestinationTestRequest | EmailDestinationTestRequest): The test connection request payload.
|
|
140
|
+
**kwargs: Arbitrary keyword arguments.
|
|
141
|
+
"""
|
|
142
|
+
self.api_client.post(
|
|
143
|
+
resource_path=f"{self._resource_path}/test",
|
|
144
|
+
data=request.model_dump(),
|
|
145
|
+
response_types_map={"204": None},
|
|
146
|
+
**kwargs,
|
|
147
|
+
)
|
|
148
|
+
|
|
109
149
|
def update(
|
|
110
150
|
self,
|
|
111
151
|
destination_id: str,
|
|
112
152
|
*,
|
|
113
153
|
name: Optional[str] = None,
|
|
114
|
-
params:
|
|
154
|
+
params: DestinationParams | None = None,
|
|
115
155
|
**kwargs,
|
|
116
|
-
) ->
|
|
156
|
+
) -> Destination:
|
|
117
157
|
"""
|
|
118
158
|
Updates a destination.
|
|
119
159
|
|
|
@@ -6,12 +6,15 @@ from typing import Literal
|
|
|
6
6
|
from typing import Optional
|
|
7
7
|
from typing import TypeAlias
|
|
8
8
|
|
|
9
|
+
from jsonschema import Draft7Validator, SchemaError
|
|
10
|
+
|
|
9
11
|
from pydantic import BaseModel, ConfigDict
|
|
10
12
|
from pydantic import Discriminator
|
|
11
13
|
from pydantic import Field
|
|
12
14
|
from pydantic import field_validator
|
|
13
15
|
from pydantic import HttpUrl
|
|
14
16
|
from pydantic import UUID4
|
|
17
|
+
import pydantic
|
|
15
18
|
|
|
16
19
|
from superwise_api.models import SuperwiseEntity
|
|
17
20
|
from superwise_api.models.agent.flowise import FlowiseCredentialUserInput
|
|
@@ -99,6 +102,15 @@ class AgentType(str, Enum):
|
|
|
99
102
|
FLOWISE = "Flowise"
|
|
100
103
|
|
|
101
104
|
|
|
105
|
+
class ReactAgentResponseMode(str, Enum):
|
|
106
|
+
TEXT = "text"
|
|
107
|
+
JSON_SCHEMA = "json_schema"
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class ReactAgentResponseJsonSchema(BaseModel):
|
|
111
|
+
model_config = ConfigDict(extra="allow")
|
|
112
|
+
|
|
113
|
+
|
|
102
114
|
class SuperwiseConfig(SuperwiseEntity):
|
|
103
115
|
framework: Literal[Framework.SUPERWISE.value] = Framework.SUPERWISE.value
|
|
104
116
|
show_cites: bool = Field(default=False)
|
|
@@ -109,6 +121,28 @@ class SuperwiseConfig(SuperwiseEntity):
|
|
|
109
121
|
class ReactAgentConfig(SuperwiseConfig):
|
|
110
122
|
type: Literal[AgentType.REACT_AGENT.value] = AgentType.REACT_AGENT.value
|
|
111
123
|
tools: List[ToolDef]
|
|
124
|
+
response_mode: ReactAgentResponseMode = Field(default=ReactAgentResponseMode.TEXT.value)
|
|
125
|
+
json_schema_response: ReactAgentResponseJsonSchema | None = None
|
|
126
|
+
|
|
127
|
+
@pydantic.model_validator(mode="after")
|
|
128
|
+
def validate_json_schema_response(self) -> "ReactAgentConfig":
|
|
129
|
+
if self.response_mode != ReactAgentResponseMode.JSON_SCHEMA:
|
|
130
|
+
return self
|
|
131
|
+
|
|
132
|
+
if self.json_schema_response is None:
|
|
133
|
+
raise ValueError("'json_schema_response' is required when response_mode is 'json_schema'")
|
|
134
|
+
|
|
135
|
+
schema_dict = self.json_schema_response.model_dump(exclude_none=True)
|
|
136
|
+
|
|
137
|
+
if "properties" not in schema_dict:
|
|
138
|
+
raise ValueError("'properties' is required in the schema")
|
|
139
|
+
|
|
140
|
+
try:
|
|
141
|
+
Draft7Validator.check_schema(schema_dict)
|
|
142
|
+
except SchemaError as e:
|
|
143
|
+
raise ValueError(f"Schema validation error: {e.message}") from e
|
|
144
|
+
|
|
145
|
+
return self
|
|
112
146
|
|
|
113
147
|
|
|
114
148
|
AdvancedAgentConfig: TypeAlias = ReactAgentConfig
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from uuid import UUID
|
|
2
|
+
|
|
3
|
+
from superwise_api.models import SuperwiseEntity
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class EventFeedbackData(SuperwiseEntity):
|
|
7
|
+
interaction_id: UUID
|
|
8
|
+
question: str
|
|
9
|
+
answer: str
|
|
10
|
+
is_positive: bool
|
|
11
|
+
negative_feedback_category_harmful: bool
|
|
12
|
+
negative_feedback_category_untrue: bool
|
|
13
|
+
negative_feedback_category_unhelpful: bool
|
|
14
|
+
negative_feedback_category_other: bool
|
|
15
|
+
feedback_description: str
|
|
16
|
+
agent_id: str
|
|
@@ -70,6 +70,9 @@ class AskResponsePayload(SuperwiseEntity):
|
|
|
70
70
|
metadata: Union[ResponseMetadata, Empty] = Field(
|
|
71
71
|
default=Empty(), description="The metadata associated with the response."
|
|
72
72
|
)
|
|
73
|
+
interaction_id: Optional[str] = Field(
|
|
74
|
+
default=None, description="Unique identifier for this interaction, used for feedback."
|
|
75
|
+
)
|
|
73
76
|
|
|
74
77
|
@classmethod
|
|
75
78
|
def from_dict(cls, data: dict) -> "AskResponsePayload":
|
|
@@ -88,3 +88,7 @@ class SqlQueryResponse(SuperwiseEntity):
|
|
|
88
88
|
None,
|
|
89
89
|
description="Query results. None when validate_only=True or when validation fails.",
|
|
90
90
|
)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class NaturalLanguageQueryResponse(SqlQueryResponse):
|
|
94
|
+
sql: str | None = Field(None, description="The SQL generated from your natural language query")
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from datetime import datetime
|
|
2
|
+
from enum import Enum
|
|
3
|
+
from typing import Union, Annotated
|
|
4
|
+
from uuid import UUID
|
|
5
|
+
|
|
6
|
+
from pydantic import field_serializer, ConfigDict, BaseModel, Discriminator
|
|
7
|
+
|
|
8
|
+
from superwise_api.models import SuperwiseEntity
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class DestinationType(str, Enum):
|
|
12
|
+
SLACK = "slack"
|
|
13
|
+
TEAMS = "teams"
|
|
14
|
+
EMAIL = "email"
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class SlackDestinationParams(SuperwiseEntity):
|
|
18
|
+
channel_id: str
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TeamsDestinationParams(SuperwiseEntity):
|
|
22
|
+
webhook_url: str
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class EmailDestinationParams(SuperwiseEntity):
|
|
26
|
+
emails: list[str]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class DestinationBase(BaseModel):
|
|
30
|
+
model_config = ConfigDict(use_enum_values=True)
|
|
31
|
+
integration_type: DestinationType
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class TeamsDestinationTestRequest(TeamsDestinationParams, DestinationBase):
|
|
35
|
+
integration_type: DestinationType = DestinationType.TEAMS.value
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class SlackDestinationTestRequest(SlackDestinationParams, DestinationBase):
|
|
39
|
+
integration_type: DestinationType = DestinationType.SLACK.value
|
|
40
|
+
integration_id: UUID
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class EmailDestinationTestRequest(EmailDestinationParams, DestinationBase):
|
|
44
|
+
integration_type: DestinationType = DestinationType.EMAIL.value
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
DestinationParams = Union[SlackDestinationParams, TeamsDestinationParams, EmailDestinationParams]
|
|
48
|
+
DestinationTestRequest = Annotated[
|
|
49
|
+
TeamsDestinationTestRequest,
|
|
50
|
+
SlackDestinationTestRequest,
|
|
51
|
+
EmailDestinationTestRequest,
|
|
52
|
+
Discriminator("integration_type"),
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class Destination(SuperwiseEntity):
|
|
57
|
+
id: UUID
|
|
58
|
+
name: str
|
|
59
|
+
integration_id: UUID
|
|
60
|
+
params: SlackDestinationParams | TeamsDestinationParams | EmailDestinationParams
|
|
61
|
+
updated_at: datetime
|
|
62
|
+
created_at: datetime
|
|
63
|
+
created_by: str
|
|
64
|
+
tenant_id: str
|
|
65
|
+
|
|
66
|
+
@field_serializer("created_at", "updated_at")
|
|
67
|
+
def serialize_dt(self, dt: datetime) -> str:
|
|
68
|
+
return dt.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
|
|
69
|
+
|
|
70
|
+
def to_dict(self) -> dict:
|
|
71
|
+
dict_ = self.model_dump(exclude_none=True)
|
|
72
|
+
return dict_
|
|
73
|
+
|
|
74
|
+
@classmethod
|
|
75
|
+
def from_dict(cls, dict_: dict) -> "Destination":
|
|
76
|
+
if "webhook_url" in dict_["params"]:
|
|
77
|
+
dict_["params"] = TeamsDestinationParams(**dict_["params"])
|
|
78
|
+
elif "emails" in dict_["params"]:
|
|
79
|
+
dict_["params"] = EmailDestinationParams(**dict_["params"])
|
|
80
|
+
else:
|
|
81
|
+
dict_["params"] = SlackDestinationParams(**dict_["params"])
|
|
82
|
+
return cls(**dict_)
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
from uuid import UUID, uuid4
|
|
2
|
-
|
|
3
|
-
from superwise_api.models import SuperwiseEntity
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class EventFeedbackData(SuperwiseEntity):
|
|
7
|
-
answer_id: UUID
|
|
8
|
-
question: str
|
|
9
|
-
answer: str
|
|
10
|
-
is_positive: bool
|
|
11
|
-
negative_feedback_category_harmful: bool
|
|
12
|
-
negative_feedback_category_untrue: bool
|
|
13
|
-
negative_feedback_category_unhelpful: bool
|
|
14
|
-
negative_feedback_category_other: bool
|
|
15
|
-
feedback_description: str
|
|
16
|
-
agent_id: str
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
def create_event_feedback(
|
|
20
|
-
agent_id: str,
|
|
21
|
-
question: str,
|
|
22
|
-
answer: str,
|
|
23
|
-
is_positive: bool = True,
|
|
24
|
-
negative_feedback_category_harmful: bool = False,
|
|
25
|
-
negative_feedback_category_untrue: bool = False,
|
|
26
|
-
negative_feedback_category_unhelpful: bool = False,
|
|
27
|
-
negative_feedback_category_other: bool = False,
|
|
28
|
-
feedback_description: str = "",
|
|
29
|
-
) -> EventFeedbackData:
|
|
30
|
-
return EventFeedbackData(
|
|
31
|
-
agent_id=agent_id,
|
|
32
|
-
answer_id=uuid4(),
|
|
33
|
-
question=question,
|
|
34
|
-
answer=answer,
|
|
35
|
-
is_positive=is_positive,
|
|
36
|
-
negative_feedback_category_harmful=negative_feedback_category_harmful,
|
|
37
|
-
negative_feedback_category_untrue=negative_feedback_category_untrue,
|
|
38
|
-
negative_feedback_category_unhelpful=negative_feedback_category_unhelpful,
|
|
39
|
-
negative_feedback_category_other=negative_feedback_category_other,
|
|
40
|
-
feedback_description=feedback_description,
|
|
41
|
-
)
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
from datetime import datetime
|
|
2
|
-
from uuid import UUID
|
|
3
|
-
|
|
4
|
-
from pydantic import field_serializer
|
|
5
|
-
|
|
6
|
-
from superwise_api.models import SuperwiseEntity
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class SlackDestinationParams(SuperwiseEntity):
|
|
10
|
-
channel_id: str
|
|
11
|
-
|
|
12
|
-
def to_dict(self):
|
|
13
|
-
return self.model_dump()
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class Destination(SuperwiseEntity):
|
|
17
|
-
id: UUID
|
|
18
|
-
name: str
|
|
19
|
-
integration_id: UUID
|
|
20
|
-
params: SlackDestinationParams
|
|
21
|
-
updated_at: datetime
|
|
22
|
-
created_at: datetime
|
|
23
|
-
created_by: str
|
|
24
|
-
tenant_id: str
|
|
25
|
-
|
|
26
|
-
@field_serializer("created_at", "updated_at")
|
|
27
|
-
def serialize_dt(self, dt: datetime) -> str:
|
|
28
|
-
return dt.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]
|
|
29
|
-
|
|
30
|
-
def to_dict(self) -> dict:
|
|
31
|
-
dict_ = self.model_dump(exclude_none=True)
|
|
32
|
-
return dict_
|
|
33
|
-
|
|
34
|
-
@classmethod
|
|
35
|
-
def from_dict(cls, dict_: dict) -> "Destination":
|
|
36
|
-
dict_["params"] = SlackDestinationParams(**dict_["params"])
|
|
37
|
-
return cls(**dict_)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/client/models/threshold_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dashboard_item/__init__.py
RENAMED
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dashboard_item/dashboard_item.py
RENAMED
|
File without changes
|
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset/dataset_schema.py
RENAMED
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset_source/__init__.py
RENAMED
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/dataset_source/dataset_source.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/model_provider/__init__.py
RENAMED
|
File without changes
|
{superwise_api-4.16.0 → superwise_api-4.17.0}/superwise_api/models/model_provider/model_provider.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|