kainguru-sdk 0.2.11.dev0__tar.gz → 0.2.13.dev0__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.
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/PKG-INFO +1 -1
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/pyproject.toml +1 -1
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/__init__.py +4 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/async_client.py +2 -1
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/client.py +2 -1
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/models.py +213 -74
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/resources/__init__.py +3 -0
- kainguru_sdk-0.2.13.dev0/src/kainguru/resources/_common.py +88 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/resources/executions.py +47 -3
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/resources/finetuning.py +26 -0
- kainguru_sdk-0.2.13.dev0/src/kainguru/resources/rag.py +254 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/tests/resources/openapi.json +1254 -372
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/tests/test_executions.py +51 -0
- kainguru_sdk-0.2.13.dev0/tests/test_finetuning.py +109 -0
- kainguru_sdk-0.2.13.dev0/tests/test_rag.py +218 -0
- kainguru_sdk-0.2.11.dev0/src/kainguru/resources/_common.py +0 -35
- kainguru_sdk-0.2.11.dev0/tests/test_finetuning.py +0 -53
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/.gitignore +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/MAINTAINERS.md +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/Makefile +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/README.md +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/_config.py +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/_errors.py +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/_polling.py +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/_transport.py +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/src/kainguru/py.typed +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/tests/conftest.py +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/tests/test_auth.py +0 -0
- {kainguru_sdk-0.2.11.dev0 → kainguru_sdk-0.2.13.dev0}/tests/test_polling.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: kainguru-sdk
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.13.dev0
|
|
4
4
|
Summary: Python SDK for the Kainguru ML platform — run models and fine-tune them.
|
|
5
5
|
Project-URL: Homepage, https://kainguru.com
|
|
6
6
|
Project-URL: Repository, https://github.com/kainguru/kainguru
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "kainguru-sdk"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.13.dev0"
|
|
8
8
|
description = "Python SDK for the Kainguru ML platform — run models and fine-tune them."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -22,6 +22,7 @@ from .models import (
|
|
|
22
22
|
ModelFineTunedDetailDto,
|
|
23
23
|
ModelStatus,
|
|
24
24
|
)
|
|
25
|
+
from .resources import AsyncRagResource, RagResource
|
|
25
26
|
|
|
26
27
|
__version__ = "0.1.0"
|
|
27
28
|
|
|
@@ -39,6 +40,9 @@ __all__ = [
|
|
|
39
40
|
"KainguruRateLimitError",
|
|
40
41
|
"KainguruTimeoutError",
|
|
41
42
|
"KainguruConnectionError",
|
|
43
|
+
# Resources
|
|
44
|
+
"RagResource",
|
|
45
|
+
"AsyncRagResource",
|
|
42
46
|
# Models
|
|
43
47
|
"ModelStatus",
|
|
44
48
|
"ModelExecResponseDto",
|
|
@@ -13,7 +13,7 @@ from ._config import (
|
|
|
13
13
|
KainguruConfig,
|
|
14
14
|
)
|
|
15
15
|
from ._transport import AsyncTransport, enable_debug_logging
|
|
16
|
-
from .resources import AsyncExecutionsResource, AsyncFineTuningResource
|
|
16
|
+
from .resources import AsyncExecutionsResource, AsyncFineTuningResource, AsyncRagResource
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class AsyncKainguruClient:
|
|
@@ -58,6 +58,7 @@ class AsyncKainguruClient:
|
|
|
58
58
|
self._transport = AsyncTransport(client, self._config)
|
|
59
59
|
self.executions = AsyncExecutionsResource(self._transport)
|
|
60
60
|
self.fine_tuning = AsyncFineTuningResource(self._transport)
|
|
61
|
+
self.rag = AsyncRagResource(self._transport)
|
|
61
62
|
|
|
62
63
|
@property
|
|
63
64
|
def config(self) -> KainguruConfig:
|
|
@@ -13,7 +13,7 @@ from ._config import (
|
|
|
13
13
|
KainguruConfig,
|
|
14
14
|
)
|
|
15
15
|
from ._transport import Transport, enable_debug_logging
|
|
16
|
-
from .resources import ExecutionsResource, FineTuningResource
|
|
16
|
+
from .resources import ExecutionsResource, FineTuningResource, RagResource
|
|
17
17
|
|
|
18
18
|
|
|
19
19
|
class KainguruClient:
|
|
@@ -58,6 +58,7 @@ class KainguruClient:
|
|
|
58
58
|
self._transport = Transport(client, self._config)
|
|
59
59
|
self.executions = ExecutionsResource(self._transport)
|
|
60
60
|
self.fine_tuning = FineTuningResource(self._transport)
|
|
61
|
+
self.rag = RagResource(self._transport)
|
|
61
62
|
|
|
62
63
|
@property
|
|
63
64
|
def config(self) -> KainguruConfig:
|
|
@@ -7,12 +7,13 @@ from enum import Enum
|
|
|
7
7
|
from typing import Any
|
|
8
8
|
from uuid import UUID
|
|
9
9
|
|
|
10
|
-
from pydantic import AwareDatetime, BaseModel, constr
|
|
10
|
+
from pydantic import AwareDatetime, BaseModel, Field, constr
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class
|
|
13
|
+
class RagIngestRequestDto(BaseModel):
|
|
14
14
|
name: constr(min_length=1)
|
|
15
|
-
|
|
15
|
+
fileIds: list[UUID] = Field(..., min_length=1)
|
|
16
|
+
params: dict[str, Any] | None = None
|
|
16
17
|
|
|
17
18
|
|
|
18
19
|
class CategoryShortDto(BaseModel):
|
|
@@ -24,39 +25,54 @@ class CategoryShortDto(BaseModel):
|
|
|
24
25
|
modifiedDate: AwareDatetime | None = None
|
|
25
26
|
|
|
26
27
|
|
|
27
|
-
class
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
class FileType(Enum):
|
|
29
|
+
JPEG = 'JPEG'
|
|
30
|
+
PNG = 'PNG'
|
|
31
|
+
WEBP = 'WEBP'
|
|
32
|
+
GIF = 'GIF'
|
|
33
|
+
BMP = 'BMP'
|
|
34
|
+
TIFF = 'TIFF'
|
|
35
|
+
SVG = 'SVG'
|
|
36
|
+
MP3 = 'MP3'
|
|
37
|
+
WAV = 'WAV'
|
|
38
|
+
FLAC = 'FLAC'
|
|
39
|
+
OGG = 'OGG'
|
|
40
|
+
M4A = 'M4A'
|
|
41
|
+
AAC = 'AAC'
|
|
42
|
+
WEBM_AUDIO = 'WEBM_AUDIO'
|
|
43
|
+
MP4 = 'MP4'
|
|
44
|
+
WEBM_VIDEO = 'WEBM_VIDEO'
|
|
45
|
+
MOV = 'MOV'
|
|
46
|
+
AVI = 'AVI'
|
|
47
|
+
MKV = 'MKV'
|
|
48
|
+
JSON = 'JSON'
|
|
49
|
+
JSONL = 'JSONL'
|
|
50
|
+
TXT = 'TXT'
|
|
51
|
+
CSV = 'CSV'
|
|
52
|
+
PDF = 'PDF'
|
|
53
|
+
DOCX = 'DOCX'
|
|
54
|
+
ZIP = 'ZIP'
|
|
55
|
+
PY = 'PY'
|
|
56
|
+
YAML = 'YAML'
|
|
57
|
+
MD = 'MD'
|
|
58
|
+
OBJ = 'OBJ'
|
|
59
|
+
GLB = 'GLB'
|
|
60
|
+
GLTF = 'GLTF'
|
|
61
|
+
PLY = 'PLY'
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class AccessLevel(Enum):
|
|
65
|
+
PUBLIC = 'PUBLIC'
|
|
66
|
+
PRIVATE = 'PRIVATE'
|
|
42
67
|
|
|
43
68
|
|
|
44
|
-
class
|
|
69
|
+
class FileDto(BaseModel):
|
|
45
70
|
id: UUID | None = None
|
|
46
|
-
createDate: AwareDatetime | None = None
|
|
47
|
-
modifiedDate: AwareDatetime | None = None
|
|
48
71
|
name: str | None = None
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
mediaTypes: list[str] | None = None
|
|
54
|
-
scope: Scope | None = None
|
|
55
|
-
label: str | None = None
|
|
56
|
-
defaultValue: Any | None = None
|
|
57
|
-
allowedValues: list[Any] | None = None
|
|
58
|
-
requirementGroup: list[str] | None = None
|
|
59
|
-
requiredWhen: dict[str, Any] | None = None
|
|
72
|
+
url: str | None = None
|
|
73
|
+
s3Key: str | None = None
|
|
74
|
+
fileType: FileType | None = None
|
|
75
|
+
accessLevel: AccessLevel | None = None
|
|
60
76
|
|
|
61
77
|
|
|
62
78
|
class AccessType(Enum):
|
|
@@ -90,14 +106,28 @@ class ModelStatus(Enum):
|
|
|
90
106
|
DELETED = 'DELETED'
|
|
91
107
|
|
|
92
108
|
|
|
93
|
-
class
|
|
109
|
+
class RagOperation(Enum):
|
|
110
|
+
RAG_INGEST = 'RAG_INGEST'
|
|
111
|
+
RAG_APPEND = 'RAG_APPEND'
|
|
112
|
+
RAG_DOC_DELETE = 'RAG_DOC_DELETE'
|
|
113
|
+
RAG_DELETE = 'RAG_DELETE'
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class RagOperationResultDto(BaseModel):
|
|
94
117
|
id: UUID | None = None
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
118
|
+
operation: RagOperation | None = None
|
|
119
|
+
status: ModelStatus | None = None
|
|
120
|
+
added: list[str] | None = None
|
|
121
|
+
replaced: list[str] | None = None
|
|
122
|
+
skipped: list[str] | None = None
|
|
123
|
+
deleted: list[dict[str, Any]] | None = None
|
|
124
|
+
notFound: list[str] | None = None
|
|
125
|
+
sourceFiles: list[str] | None = None
|
|
126
|
+
numChunks: int | None = None
|
|
127
|
+
verified: bool | None = None
|
|
128
|
+
startDate: AwareDatetime | None = None
|
|
129
|
+
endDate: AwareDatetime | None = None
|
|
130
|
+
duration: float | None = None
|
|
101
131
|
|
|
102
132
|
|
|
103
133
|
class CommonApiResponse(BaseModel):
|
|
@@ -111,9 +141,80 @@ class FieldError(BaseModel):
|
|
|
111
141
|
message: str | None = None
|
|
112
142
|
|
|
113
143
|
|
|
144
|
+
class RagFileSelectionRequestDto(BaseModel):
|
|
145
|
+
fileIds: list[UUID] = Field(..., min_length=1)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class ModelFineTuneRequestDto(BaseModel):
|
|
149
|
+
name: constr(min_length=1)
|
|
150
|
+
input: dict[str, Any]
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
class FineTuneResultDto(BaseModel):
|
|
154
|
+
id: UUID | None = None
|
|
155
|
+
status: ModelStatus | None = None
|
|
156
|
+
input: dict[str, Any] | None = None
|
|
157
|
+
output: Any | None = None
|
|
158
|
+
step: str | None = None
|
|
159
|
+
percent: float | None = None
|
|
160
|
+
stepsHistory: list[dict[str, Any]] | None = None
|
|
161
|
+
startDate: AwareDatetime | None = None
|
|
162
|
+
endDate: AwareDatetime | None = None
|
|
163
|
+
duration: float | None = None
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
class InputType(Enum):
|
|
167
|
+
STRING = 'STRING'
|
|
168
|
+
INTEGER = 'INTEGER'
|
|
169
|
+
FLOAT = 'FLOAT'
|
|
170
|
+
BOOLEAN = 'BOOLEAN'
|
|
171
|
+
DICT = 'DICT'
|
|
172
|
+
PATH = 'PATH'
|
|
173
|
+
PATH_ARRAY = 'PATH_ARRAY'
|
|
174
|
+
LABELED_PATH_ARRAY = 'LABELED_PATH_ARRAY'
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
class Scope(Enum):
|
|
178
|
+
BASE_ONLY = 'BASE_ONLY'
|
|
179
|
+
FINE_TUNED_ONLY = 'FINE_TUNED_ONLY'
|
|
180
|
+
BOTH = 'BOTH'
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class ModelExecInputDto(BaseModel):
|
|
184
|
+
id: UUID | None = None
|
|
185
|
+
createDate: AwareDatetime | None = None
|
|
186
|
+
modifiedDate: AwareDatetime | None = None
|
|
187
|
+
name: str | None = None
|
|
188
|
+
description: str | None = None
|
|
189
|
+
inputType: InputType | None = None
|
|
190
|
+
validations: dict[str, Any] | None = None
|
|
191
|
+
required: bool | None = None
|
|
192
|
+
mediaTypes: list[str] | None = None
|
|
193
|
+
scope: Scope | None = None
|
|
194
|
+
label: str | None = None
|
|
195
|
+
defaultValue: Any | None = None
|
|
196
|
+
allowedValues: list[Any] | None = None
|
|
197
|
+
requirementGroup: list[str] | None = None
|
|
198
|
+
requiredWhen: dict[str, Any] | None = None
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
class UserDto(BaseModel):
|
|
202
|
+
id: UUID | None = None
|
|
203
|
+
username: str | None = None
|
|
204
|
+
fullname: str | None = None
|
|
205
|
+
email: str | None = None
|
|
206
|
+
emailVerified: bool | None = None
|
|
207
|
+
createDate: AwareDatetime | None = None
|
|
208
|
+
modifiedDate: AwareDatetime | None = None
|
|
209
|
+
|
|
210
|
+
|
|
114
211
|
class ModelExecRequestDto(BaseModel):
|
|
115
212
|
input: dict[str, Any]
|
|
116
213
|
outputFormat: str | None = None
|
|
214
|
+
ragHandle: str | None = None
|
|
215
|
+
ragTopK: int | None = None
|
|
216
|
+
ragMinScore: float | None = None
|
|
217
|
+
ragPromptMode: str | None = None
|
|
117
218
|
|
|
118
219
|
|
|
119
220
|
class Status(Enum):
|
|
@@ -131,20 +232,6 @@ class ApplicationDto(BaseModel):
|
|
|
131
232
|
archived: bool | None = None
|
|
132
233
|
|
|
133
234
|
|
|
134
|
-
class ExecutionResultDto(BaseModel):
|
|
135
|
-
id: UUID | None = None
|
|
136
|
-
input: dict[str, Any] | None = None
|
|
137
|
-
output: Any | None = None
|
|
138
|
-
inputFormats: dict[str, str] | None = None
|
|
139
|
-
outputFormat: str | None = None
|
|
140
|
-
step: str | None = None
|
|
141
|
-
percent: float | None = None
|
|
142
|
-
stepsHistory: list[dict[str, Any]] | None = None
|
|
143
|
-
startDate: AwareDatetime | None = None
|
|
144
|
-
endDate: AwareDatetime | None = None
|
|
145
|
-
duration: float | None = None
|
|
146
|
-
|
|
147
|
-
|
|
148
235
|
class ModelExecFineTunedRefDto(BaseModel):
|
|
149
236
|
id: UUID | None = None
|
|
150
237
|
mlflowModelId: str | None = None
|
|
@@ -156,28 +243,32 @@ class ModelExecModelRefDto(BaseModel):
|
|
|
156
243
|
version: str | None = None
|
|
157
244
|
|
|
158
245
|
|
|
159
|
-
class
|
|
246
|
+
class RagRequestDto(BaseModel):
|
|
247
|
+
handle: str | None = None
|
|
248
|
+
topK: int | None = None
|
|
249
|
+
minScore: float | None = None
|
|
250
|
+
promptMode: str | None = None
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class SourceDto(BaseModel):
|
|
254
|
+
sourceFile: str | None = None
|
|
255
|
+
chunkIndex: int | None = None
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class RagKnowledgeBaseDto(BaseModel):
|
|
160
259
|
id: UUID | None = None
|
|
260
|
+
name: str | None = None
|
|
261
|
+
ragHandle: str | None = None
|
|
161
262
|
status: ModelStatus | None = None
|
|
162
263
|
model: ModelExecModelRefDto | None = None
|
|
163
|
-
fineTunedModel: ModelExecFineTunedRefDto | None = None
|
|
164
|
-
application: ApplicationDto | None = None
|
|
165
|
-
execution: ExecutionResultDto | None = None
|
|
166
264
|
createDate: AwareDatetime | None = None
|
|
167
265
|
modifiedDate: AwareDatetime | None = None
|
|
168
266
|
|
|
169
267
|
|
|
170
|
-
class
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
output: Any | None = None
|
|
175
|
-
step: str | None = None
|
|
176
|
-
percent: float | None = None
|
|
177
|
-
stepsHistory: list[dict[str, Any]] | None = None
|
|
178
|
-
startDate: AwareDatetime | None = None
|
|
179
|
-
endDate: AwareDatetime | None = None
|
|
180
|
-
duration: float | None = None
|
|
268
|
+
class RagKnowledgeBaseListApiResponse(BaseModel):
|
|
269
|
+
success: bool | None = None
|
|
270
|
+
code: int | None = None
|
|
271
|
+
data: list[RagKnowledgeBaseDto] | None = None
|
|
181
272
|
|
|
182
273
|
|
|
183
274
|
class ModelListDto(BaseModel):
|
|
@@ -199,6 +290,18 @@ class ModelListDto(BaseModel):
|
|
|
199
290
|
banner: str | None = None
|
|
200
291
|
|
|
201
292
|
|
|
293
|
+
class RagKnowledgeBaseDetailDto(BaseModel):
|
|
294
|
+
id: UUID | None = None
|
|
295
|
+
name: str | None = None
|
|
296
|
+
ragHandle: str | None = None
|
|
297
|
+
status: ModelStatus | None = None
|
|
298
|
+
model: ModelListDto | None = None
|
|
299
|
+
files: list[FileDto] | None = None
|
|
300
|
+
latestOperation: RagOperationResultDto | None = None
|
|
301
|
+
createDate: AwareDatetime | None = None
|
|
302
|
+
modifiedDate: AwareDatetime | None = None
|
|
303
|
+
|
|
304
|
+
|
|
202
305
|
class ErrorDto(BaseModel):
|
|
203
306
|
success: bool | None = None
|
|
204
307
|
code: int | None = None
|
|
@@ -209,12 +312,6 @@ class ErrorDto(BaseModel):
|
|
|
209
312
|
errors: list[FieldError] | None = None
|
|
210
313
|
|
|
211
314
|
|
|
212
|
-
class ModelExecApiResponse(BaseModel):
|
|
213
|
-
success: bool | None = None
|
|
214
|
-
code: int | None = None
|
|
215
|
-
data: ModelExecResponseDto | None = None
|
|
216
|
-
|
|
217
|
-
|
|
218
315
|
class ModelFineTunedDetailDto(BaseModel):
|
|
219
316
|
id: UUID | None = None
|
|
220
317
|
name: str | None = None
|
|
@@ -230,7 +327,49 @@ class ModelFineTunedDetailDto(BaseModel):
|
|
|
230
327
|
modifiedDate: AwareDatetime | None = None
|
|
231
328
|
|
|
232
329
|
|
|
330
|
+
class ExecutionResultDto(BaseModel):
|
|
331
|
+
id: UUID | None = None
|
|
332
|
+
input: dict[str, Any] | None = None
|
|
333
|
+
output: Any | None = None
|
|
334
|
+
inputFormats: dict[str, str] | None = None
|
|
335
|
+
outputFormat: str | None = None
|
|
336
|
+
step: str | None = None
|
|
337
|
+
percent: float | None = None
|
|
338
|
+
stepsHistory: list[dict[str, Any]] | None = None
|
|
339
|
+
startDate: AwareDatetime | None = None
|
|
340
|
+
endDate: AwareDatetime | None = None
|
|
341
|
+
duration: float | None = None
|
|
342
|
+
mode: str | None = None
|
|
343
|
+
sources: list[SourceDto] | None = None
|
|
344
|
+
loraRunId: str | None = None
|
|
345
|
+
ragHandle: str | None = None
|
|
346
|
+
ragRequest: RagRequestDto | None = None
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
class ModelExecResponseDto(BaseModel):
|
|
350
|
+
id: UUID | None = None
|
|
351
|
+
status: ModelStatus | None = None
|
|
352
|
+
model: ModelExecModelRefDto | None = None
|
|
353
|
+
fineTunedModel: ModelExecFineTunedRefDto | None = None
|
|
354
|
+
application: ApplicationDto | None = None
|
|
355
|
+
execution: ExecutionResultDto | None = None
|
|
356
|
+
createDate: AwareDatetime | None = None
|
|
357
|
+
modifiedDate: AwareDatetime | None = None
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
class RagKnowledgeBaseApiResponse(BaseModel):
|
|
361
|
+
success: bool | None = None
|
|
362
|
+
code: int | None = None
|
|
363
|
+
data: RagKnowledgeBaseDetailDto | None = None
|
|
364
|
+
|
|
365
|
+
|
|
233
366
|
class ModelFineTuneApiResponse(BaseModel):
|
|
234
367
|
success: bool | None = None
|
|
235
368
|
code: int | None = None
|
|
236
369
|
data: ModelFineTunedDetailDto | None = None
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
class ModelExecApiResponse(BaseModel):
|
|
373
|
+
success: bool | None = None
|
|
374
|
+
code: int | None = None
|
|
375
|
+
data: ModelExecResponseDto | None = None
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
from .executions import AsyncExecutionsResource, ExecutionsResource
|
|
2
2
|
from .finetuning import AsyncFineTuningResource, FineTuningResource
|
|
3
|
+
from .rag import AsyncRagResource, RagResource
|
|
3
4
|
|
|
4
5
|
__all__ = [
|
|
5
6
|
"ExecutionsResource",
|
|
6
7
|
"AsyncExecutionsResource",
|
|
7
8
|
"FineTuningResource",
|
|
8
9
|
"AsyncFineTuningResource",
|
|
10
|
+
"RagResource",
|
|
11
|
+
"AsyncRagResource",
|
|
9
12
|
]
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""Helpers shared across sync and async resources."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
#: A RAG knowledge base's *latest operation* is terminal at these statuses. Unlike
|
|
8
|
+
#: executions/fine-tuning, RAG also treats CANCELLED/DELETED as terminal since
|
|
9
|
+
#: `cancel`/`delete` are themselves operations callers may want to await.
|
|
10
|
+
_RAG_TERMINAL_STATUSES = ("COMPLETED", "FAILED", "CANCELLED", "DELETED")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def is_terminal(dto: object) -> bool:
|
|
14
|
+
"""COMPLETED / FAILED are terminal; REGISTERED is not (matches the Java SDK)."""
|
|
15
|
+
status = getattr(dto, "status", None)
|
|
16
|
+
value = getattr(status, "value", status)
|
|
17
|
+
return value in ("COMPLETED", "FAILED")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def is_rag_terminal(dto: object) -> bool:
|
|
21
|
+
"""Terminal check for RAG knowledge base polling.
|
|
22
|
+
|
|
23
|
+
Reads ``dto.latestOperation.status`` rather than ``dto.status``: the knowledge
|
|
24
|
+
base's own ``status`` stays ``COMPLETED`` while an append or document-delete
|
|
25
|
+
operation is in flight, so polling it directly would return prematurely (or
|
|
26
|
+
never reflect append/delete completion at all). Terminal values are
|
|
27
|
+
``COMPLETED``, ``FAILED``, ``CANCELLED``, ``DELETED``.
|
|
28
|
+
"""
|
|
29
|
+
latest_operation = getattr(dto, "latestOperation", None)
|
|
30
|
+
if latest_operation is None:
|
|
31
|
+
return False
|
|
32
|
+
status = getattr(latest_operation, "status", None)
|
|
33
|
+
value = getattr(status, "value", status)
|
|
34
|
+
return value in _RAG_TERMINAL_STATUSES
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def execute_args(
|
|
38
|
+
ml_flow_id: str,
|
|
39
|
+
input: dict[str, Any],
|
|
40
|
+
output_format: str | None,
|
|
41
|
+
exec_id: str | None,
|
|
42
|
+
rag_handle: str | None = None,
|
|
43
|
+
rag_top_k: int | None = None,
|
|
44
|
+
rag_min_score: float | None = None,
|
|
45
|
+
rag_prompt_mode: str | None = None,
|
|
46
|
+
) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
47
|
+
params: dict[str, Any] = {"mlFlowId": ml_flow_id}
|
|
48
|
+
if exec_id:
|
|
49
|
+
params["execId"] = exec_id
|
|
50
|
+
body: dict[str, Any] = {"input": input or {}, "outputFormat": output_format}
|
|
51
|
+
if rag_handle is not None:
|
|
52
|
+
body["ragHandle"] = rag_handle
|
|
53
|
+
if rag_top_k is not None:
|
|
54
|
+
body["ragTopK"] = rag_top_k
|
|
55
|
+
if rag_min_score is not None:
|
|
56
|
+
body["ragMinScore"] = rag_min_score
|
|
57
|
+
if rag_prompt_mode is not None:
|
|
58
|
+
body["ragPromptMode"] = rag_prompt_mode
|
|
59
|
+
return params, body
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def fine_tune_args(
|
|
63
|
+
model_id: str,
|
|
64
|
+
name: str,
|
|
65
|
+
input: dict[str, Any],
|
|
66
|
+
) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
67
|
+
params: dict[str, Any] = {"modelId": model_id}
|
|
68
|
+
body: dict[str, Any] = {"name": name, "input": input or {}}
|
|
69
|
+
return params, body
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def rag_ingest_args(
|
|
73
|
+
model_id: str,
|
|
74
|
+
name: str,
|
|
75
|
+
file_ids: list[str],
|
|
76
|
+
params: dict[str, Any] | None,
|
|
77
|
+
) -> tuple[dict[str, Any], dict[str, Any]]:
|
|
78
|
+
"""Build the ``(query, body)`` pair for ``POST /v1/rag``."""
|
|
79
|
+
query: dict[str, Any] = {"modelId": model_id}
|
|
80
|
+
body: dict[str, Any] = {"name": name, "fileIds": file_ids}
|
|
81
|
+
if params is not None:
|
|
82
|
+
body["params"] = params
|
|
83
|
+
return query, body
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def rag_file_selection_args(file_ids: list[str]) -> dict[str, Any]:
|
|
87
|
+
"""Build the request body shared by ``append`` and ``delete_documents``."""
|
|
88
|
+
return {"fileIds": file_ids}
|
|
@@ -36,12 +36,30 @@ class ExecutionsResource:
|
|
|
36
36
|
output_format: str | None = None,
|
|
37
37
|
exec_id: str | None = None,
|
|
38
38
|
*,
|
|
39
|
+
rag_handle: str | None = None,
|
|
40
|
+
rag_top_k: int | None = None,
|
|
41
|
+
rag_min_score: float | None = None,
|
|
42
|
+
rag_prompt_mode: str | None = None,
|
|
39
43
|
api_key: str | None = None,
|
|
40
44
|
) -> ModelExecResponseDto:
|
|
41
|
-
"""Submit a model run. Returns immediately (typically ``PENDING``).
|
|
45
|
+
"""Submit a model run. Returns immediately (typically ``PENDING``).
|
|
46
|
+
|
|
47
|
+
The ``rag_*`` kwargs enable retrieval-augmented generation against a
|
|
48
|
+
knowledge base previously created via ``client.rag.ingest`` (identified by
|
|
49
|
+
its ``ragHandle``).
|
|
50
|
+
"""
|
|
42
51
|
if not ml_flow_id:
|
|
43
52
|
raise KainguruConfigError("ml_flow_id is required")
|
|
44
|
-
params, body = execute_args(
|
|
53
|
+
params, body = execute_args(
|
|
54
|
+
ml_flow_id,
|
|
55
|
+
input,
|
|
56
|
+
output_format,
|
|
57
|
+
exec_id,
|
|
58
|
+
rag_handle=rag_handle,
|
|
59
|
+
rag_top_k=rag_top_k,
|
|
60
|
+
rag_min_score=rag_min_score,
|
|
61
|
+
rag_prompt_mode=rag_prompt_mode,
|
|
62
|
+
)
|
|
45
63
|
response = self._t.request("POST", _PATH, params=params, json=body, api_key=api_key)
|
|
46
64
|
return unwrap(response, ModelExecResponseDto)
|
|
47
65
|
|
|
@@ -52,6 +70,13 @@ class ExecutionsResource:
|
|
|
52
70
|
response = self._t.request("GET", f"{_PATH}/{id}", api_key=api_key)
|
|
53
71
|
return unwrap(response, ModelExecResponseDto)
|
|
54
72
|
|
|
73
|
+
def cancel(self, id: str, *, api_key: str | None = None) -> ModelExecResponseDto:
|
|
74
|
+
"""Cancel an active execution."""
|
|
75
|
+
if not id:
|
|
76
|
+
raise KainguruConfigError("id is required")
|
|
77
|
+
response = self._t.request("POST", f"{_PATH}/{id}/cancel", api_key=api_key)
|
|
78
|
+
return unwrap(response, ModelExecResponseDto)
|
|
79
|
+
|
|
55
80
|
def await_completion(
|
|
56
81
|
self,
|
|
57
82
|
id: str,
|
|
@@ -86,11 +111,24 @@ class AsyncExecutionsResource:
|
|
|
86
111
|
output_format: str | None = None,
|
|
87
112
|
exec_id: str | None = None,
|
|
88
113
|
*,
|
|
114
|
+
rag_handle: str | None = None,
|
|
115
|
+
rag_top_k: int | None = None,
|
|
116
|
+
rag_min_score: float | None = None,
|
|
117
|
+
rag_prompt_mode: str | None = None,
|
|
89
118
|
api_key: str | None = None,
|
|
90
119
|
) -> ModelExecResponseDto:
|
|
91
120
|
if not ml_flow_id:
|
|
92
121
|
raise KainguruConfigError("ml_flow_id is required")
|
|
93
|
-
params, body = execute_args(
|
|
122
|
+
params, body = execute_args(
|
|
123
|
+
ml_flow_id,
|
|
124
|
+
input,
|
|
125
|
+
output_format,
|
|
126
|
+
exec_id,
|
|
127
|
+
rag_handle=rag_handle,
|
|
128
|
+
rag_top_k=rag_top_k,
|
|
129
|
+
rag_min_score=rag_min_score,
|
|
130
|
+
rag_prompt_mode=rag_prompt_mode,
|
|
131
|
+
)
|
|
94
132
|
response = await self._t.request("POST", _PATH, params=params, json=body, api_key=api_key)
|
|
95
133
|
return unwrap(response, ModelExecResponseDto)
|
|
96
134
|
|
|
@@ -100,6 +138,12 @@ class AsyncExecutionsResource:
|
|
|
100
138
|
response = await self._t.request("GET", f"{_PATH}/{id}", api_key=api_key)
|
|
101
139
|
return unwrap(response, ModelExecResponseDto)
|
|
102
140
|
|
|
141
|
+
async def cancel(self, id: str, *, api_key: str | None = None) -> ModelExecResponseDto:
|
|
142
|
+
if not id:
|
|
143
|
+
raise KainguruConfigError("id is required")
|
|
144
|
+
response = await self._t.request("POST", f"{_PATH}/{id}/cancel", api_key=api_key)
|
|
145
|
+
return unwrap(response, ModelExecResponseDto)
|
|
146
|
+
|
|
103
147
|
async def await_completion(
|
|
104
148
|
self,
|
|
105
149
|
id: str,
|
|
@@ -51,6 +51,20 @@ class FineTuningResource:
|
|
|
51
51
|
response = self._t.request("GET", f"{_PATH}/{id}", api_key=api_key)
|
|
52
52
|
return unwrap(response, ModelFineTunedDetailDto)
|
|
53
53
|
|
|
54
|
+
def cancel(self, id: str, *, api_key: str | None = None) -> ModelFineTunedDetailDto:
|
|
55
|
+
"""Cancel an active fine-tuning job."""
|
|
56
|
+
if not id:
|
|
57
|
+
raise KainguruConfigError("id is required")
|
|
58
|
+
response = self._t.request("POST", f"{_PATH}/{id}/cancel", api_key=api_key)
|
|
59
|
+
return unwrap(response, ModelFineTunedDetailDto)
|
|
60
|
+
|
|
61
|
+
def delete(self, id: str, *, api_key: str | None = None) -> ModelFineTunedDetailDto:
|
|
62
|
+
"""Delete a fine-tuned model and its LoRA artifact."""
|
|
63
|
+
if not id:
|
|
64
|
+
raise KainguruConfigError("id is required")
|
|
65
|
+
response = self._t.request("DELETE", f"{_PATH}/{id}", api_key=api_key)
|
|
66
|
+
return unwrap(response, ModelFineTunedDetailDto)
|
|
67
|
+
|
|
54
68
|
def await_completion(
|
|
55
69
|
self,
|
|
56
70
|
id: str,
|
|
@@ -98,6 +112,18 @@ class AsyncFineTuningResource:
|
|
|
98
112
|
response = await self._t.request("GET", f"{_PATH}/{id}", api_key=api_key)
|
|
99
113
|
return unwrap(response, ModelFineTunedDetailDto)
|
|
100
114
|
|
|
115
|
+
async def cancel(self, id: str, *, api_key: str | None = None) -> ModelFineTunedDetailDto:
|
|
116
|
+
if not id:
|
|
117
|
+
raise KainguruConfigError("id is required")
|
|
118
|
+
response = await self._t.request("POST", f"{_PATH}/{id}/cancel", api_key=api_key)
|
|
119
|
+
return unwrap(response, ModelFineTunedDetailDto)
|
|
120
|
+
|
|
121
|
+
async def delete(self, id: str, *, api_key: str | None = None) -> ModelFineTunedDetailDto:
|
|
122
|
+
if not id:
|
|
123
|
+
raise KainguruConfigError("id is required")
|
|
124
|
+
response = await self._t.request("DELETE", f"{_PATH}/{id}", api_key=api_key)
|
|
125
|
+
return unwrap(response, ModelFineTunedDetailDto)
|
|
126
|
+
|
|
101
127
|
async def await_completion(
|
|
102
128
|
self,
|
|
103
129
|
id: str,
|