knowledge2 0.4.0__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.
- knowledge2-0.4.0.dist-info/METADATA +556 -0
- knowledge2-0.4.0.dist-info/RECORD +139 -0
- knowledge2-0.4.0.dist-info/WHEEL +5 -0
- knowledge2-0.4.0.dist-info/top_level.txt +1 -0
- sdk/__init__.py +70 -0
- sdk/_async_base.py +525 -0
- sdk/_async_paging.py +57 -0
- sdk/_base.py +541 -0
- sdk/_logging.py +41 -0
- sdk/_paging.py +73 -0
- sdk/_preview.py +70 -0
- sdk/_raw_response.py +25 -0
- sdk/_request_options.py +51 -0
- sdk/_transport.py +144 -0
- sdk/_validation.py +25 -0
- sdk/_validation_response.py +36 -0
- sdk/_version.py +3 -0
- sdk/async_client.py +320 -0
- sdk/async_resources/__init__.py +45 -0
- sdk/async_resources/_mixin_base.py +42 -0
- sdk/async_resources/a2a.py +230 -0
- sdk/async_resources/agents.py +489 -0
- sdk/async_resources/audit.py +145 -0
- sdk/async_resources/auth.py +133 -0
- sdk/async_resources/console.py +409 -0
- sdk/async_resources/corpora.py +276 -0
- sdk/async_resources/deployments.py +106 -0
- sdk/async_resources/documents.py +592 -0
- sdk/async_resources/feeds.py +248 -0
- sdk/async_resources/indexes.py +208 -0
- sdk/async_resources/jobs.py +165 -0
- sdk/async_resources/metadata.py +48 -0
- sdk/async_resources/models.py +102 -0
- sdk/async_resources/onboarding.py +538 -0
- sdk/async_resources/orgs.py +37 -0
- sdk/async_resources/pipelines.py +523 -0
- sdk/async_resources/projects.py +90 -0
- sdk/async_resources/search.py +262 -0
- sdk/async_resources/training.py +357 -0
- sdk/async_resources/usage.py +91 -0
- sdk/client.py +417 -0
- sdk/config.py +182 -0
- sdk/errors.py +178 -0
- sdk/examples/auth_factory.py +34 -0
- sdk/examples/batch_operations.py +57 -0
- sdk/examples/document_upload.py +56 -0
- sdk/examples/e2e_lifecycle.py +213 -0
- sdk/examples/error_handling.py +61 -0
- sdk/examples/pagination.py +64 -0
- sdk/examples/quickstart.py +36 -0
- sdk/examples/request_options.py +44 -0
- sdk/examples/search.py +64 -0
- sdk/integrations/__init__.py +57 -0
- sdk/integrations/_client.py +101 -0
- sdk/integrations/langchain/__init__.py +6 -0
- sdk/integrations/langchain/retriever.py +166 -0
- sdk/integrations/langchain/tools.py +108 -0
- sdk/integrations/llamaindex/__init__.py +11 -0
- sdk/integrations/llamaindex/filters.py +78 -0
- sdk/integrations/llamaindex/retriever.py +162 -0
- sdk/integrations/llamaindex/tools.py +109 -0
- sdk/integrations/llamaindex/vector_store.py +320 -0
- sdk/models/__init__.py +18 -0
- sdk/models/_base.py +24 -0
- sdk/models/_registry.py +457 -0
- sdk/models/a2a.py +92 -0
- sdk/models/agents.py +109 -0
- sdk/models/audit.py +28 -0
- sdk/models/auth.py +49 -0
- sdk/models/chunks.py +20 -0
- sdk/models/common.py +14 -0
- sdk/models/console.py +103 -0
- sdk/models/corpora.py +48 -0
- sdk/models/deployments.py +13 -0
- sdk/models/documents.py +126 -0
- sdk/models/embeddings.py +24 -0
- sdk/models/evaluation.py +17 -0
- sdk/models/feedback.py +9 -0
- sdk/models/feeds.py +57 -0
- sdk/models/indexes.py +36 -0
- sdk/models/jobs.py +52 -0
- sdk/models/models.py +26 -0
- sdk/models/onboarding.py +323 -0
- sdk/models/orgs.py +11 -0
- sdk/models/pipelines.py +147 -0
- sdk/models/projects.py +19 -0
- sdk/models/search.py +149 -0
- sdk/models/training.py +57 -0
- sdk/models/usage.py +39 -0
- sdk/namespaces.py +386 -0
- sdk/py.typed +0 -0
- sdk/resources/__init__.py +45 -0
- sdk/resources/_mixin_base.py +40 -0
- sdk/resources/a2a.py +230 -0
- sdk/resources/agents.py +487 -0
- sdk/resources/audit.py +144 -0
- sdk/resources/auth.py +138 -0
- sdk/resources/console.py +411 -0
- sdk/resources/corpora.py +269 -0
- sdk/resources/deployments.py +105 -0
- sdk/resources/documents.py +597 -0
- sdk/resources/feeds.py +246 -0
- sdk/resources/indexes.py +210 -0
- sdk/resources/jobs.py +164 -0
- sdk/resources/metadata.py +53 -0
- sdk/resources/models.py +99 -0
- sdk/resources/onboarding.py +542 -0
- sdk/resources/orgs.py +35 -0
- sdk/resources/pipeline_builder.py +257 -0
- sdk/resources/pipelines.py +520 -0
- sdk/resources/projects.py +87 -0
- sdk/resources/search.py +277 -0
- sdk/resources/training.py +358 -0
- sdk/resources/usage.py +92 -0
- sdk/types/__init__.py +366 -0
- sdk/types/a2a.py +88 -0
- sdk/types/agents.py +133 -0
- sdk/types/audit.py +26 -0
- sdk/types/auth.py +45 -0
- sdk/types/chunks.py +18 -0
- sdk/types/common.py +10 -0
- sdk/types/console.py +99 -0
- sdk/types/corpora.py +42 -0
- sdk/types/deployments.py +11 -0
- sdk/types/documents.py +104 -0
- sdk/types/embeddings.py +22 -0
- sdk/types/evaluation.py +15 -0
- sdk/types/feedback.py +7 -0
- sdk/types/feeds.py +61 -0
- sdk/types/indexes.py +30 -0
- sdk/types/jobs.py +50 -0
- sdk/types/models.py +22 -0
- sdk/types/onboarding.py +395 -0
- sdk/types/orgs.py +9 -0
- sdk/types/pipelines.py +177 -0
- sdk/types/projects.py +14 -0
- sdk/types/search.py +116 -0
- sdk/types/training.py +55 -0
- sdk/types/usage.py +37 -0
sdk/resources/search.py
ADDED
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"""Search resource mixin for the Knowledge2 SDK."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from sdk._request_options import RequestOptions
|
|
8
|
+
from sdk._validation import require_str
|
|
9
|
+
from sdk.resources._mixin_base import RequesterMixin
|
|
10
|
+
from sdk.types import (
|
|
11
|
+
EmbeddingModelListResponse,
|
|
12
|
+
EmbeddingsResponse,
|
|
13
|
+
FeedbackResponse,
|
|
14
|
+
SearchBatchResponse,
|
|
15
|
+
SearchGenerateResponse,
|
|
16
|
+
SearchResponse,
|
|
17
|
+
)
|
|
18
|
+
from sdk.types.search import (
|
|
19
|
+
SearchGenerationConfig,
|
|
20
|
+
SearchHybridConfig,
|
|
21
|
+
SearchRerankConfig,
|
|
22
|
+
SearchReturnConfig,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class SearchMixin(RequesterMixin):
|
|
27
|
+
def search(
|
|
28
|
+
self,
|
|
29
|
+
corpus_id: str,
|
|
30
|
+
query: str,
|
|
31
|
+
*,
|
|
32
|
+
top_k: int = 10,
|
|
33
|
+
filters: dict[str, Any] | None = None,
|
|
34
|
+
hybrid: SearchHybridConfig | dict[str, Any] | None = None,
|
|
35
|
+
rerank: SearchRerankConfig | dict[str, Any] | None = None,
|
|
36
|
+
return_config: SearchReturnConfig | dict[str, Any] | None = None,
|
|
37
|
+
request_options: RequestOptions | None = None,
|
|
38
|
+
) -> SearchResponse:
|
|
39
|
+
"""Search a corpus for relevant chunks.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
corpus_id: The corpus to search.
|
|
43
|
+
query: The search query text.
|
|
44
|
+
top_k: Maximum number of results to return.
|
|
45
|
+
filters: Optional metadata filters to narrow results.
|
|
46
|
+
hybrid: Hybrid search configuration (dense/sparse weighting).
|
|
47
|
+
rerank: Reranking configuration applied after initial retrieval.
|
|
48
|
+
return_config: Controls which fields are included in the
|
|
49
|
+
response (e.g. text, metadata, provenance).
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Search results with scored chunks, metadata, and text.
|
|
53
|
+
|
|
54
|
+
Raises:
|
|
55
|
+
NotFoundError: If the corpus does not exist.
|
|
56
|
+
Knowledge2Error: If the API request fails.
|
|
57
|
+
|
|
58
|
+
Example:
|
|
59
|
+
>>> results = client.search("corpus-123", "machine learning basics", top_k=5)
|
|
60
|
+
>>> for chunk in results["chunks"]:
|
|
61
|
+
... print(chunk["score"], chunk["text"][:80])
|
|
62
|
+
"""
|
|
63
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
64
|
+
payload: dict[str, Any] = {"query": query, "top_k": top_k}
|
|
65
|
+
if filters is not None:
|
|
66
|
+
payload["filters"] = filters
|
|
67
|
+
if hybrid is not None:
|
|
68
|
+
payload["hybrid"] = hybrid
|
|
69
|
+
if rerank is not None:
|
|
70
|
+
payload["rerank"] = rerank
|
|
71
|
+
if return_config is not None:
|
|
72
|
+
payload["return"] = return_config
|
|
73
|
+
data = self._request(
|
|
74
|
+
"POST", f"/v1/corpora/{corpus_id}/search", json=payload, request_options=request_options
|
|
75
|
+
)
|
|
76
|
+
return self._maybe_validate(data, "SearchResponse")
|
|
77
|
+
|
|
78
|
+
def search_batch(
|
|
79
|
+
self,
|
|
80
|
+
corpus_id: str,
|
|
81
|
+
queries: list[str],
|
|
82
|
+
*,
|
|
83
|
+
top_k: int = 10,
|
|
84
|
+
filters: dict[str, Any] | None = None,
|
|
85
|
+
hybrid: SearchHybridConfig | dict[str, Any] | None = None,
|
|
86
|
+
rerank: SearchRerankConfig | dict[str, Any] | None = None,
|
|
87
|
+
return_config: SearchReturnConfig | dict[str, Any] | None = None,
|
|
88
|
+
request_options: RequestOptions | None = None,
|
|
89
|
+
) -> SearchBatchResponse:
|
|
90
|
+
"""Execute multiple search queries against a corpus in a single request.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
corpus_id: The corpus to search.
|
|
94
|
+
queries: List of search query texts.
|
|
95
|
+
top_k: Maximum number of results to return per query.
|
|
96
|
+
filters: Optional metadata filters applied to all queries.
|
|
97
|
+
hybrid: Hybrid search configuration (dense/sparse weighting).
|
|
98
|
+
rerank: Reranking configuration applied after initial retrieval.
|
|
99
|
+
return_config: Controls which fields are included in each
|
|
100
|
+
query's results.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
Batch search results — one result set per input query.
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
NotFoundError: If the corpus does not exist.
|
|
107
|
+
Knowledge2Error: If the API request fails.
|
|
108
|
+
"""
|
|
109
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
110
|
+
payload: dict[str, Any] = {"queries": queries, "top_k": top_k}
|
|
111
|
+
if filters is not None:
|
|
112
|
+
payload["filters"] = filters
|
|
113
|
+
if hybrid is not None:
|
|
114
|
+
payload["hybrid"] = hybrid
|
|
115
|
+
if rerank is not None:
|
|
116
|
+
payload["rerank"] = rerank
|
|
117
|
+
if return_config is not None:
|
|
118
|
+
payload["return"] = return_config
|
|
119
|
+
data = self._request(
|
|
120
|
+
"POST",
|
|
121
|
+
f"/v1/corpora/{corpus_id}/search:batch",
|
|
122
|
+
json=payload,
|
|
123
|
+
request_options=request_options,
|
|
124
|
+
)
|
|
125
|
+
return self._maybe_validate(data, "SearchBatchResponse")
|
|
126
|
+
|
|
127
|
+
def search_generate(
|
|
128
|
+
self,
|
|
129
|
+
corpus_id: str,
|
|
130
|
+
query: str,
|
|
131
|
+
*,
|
|
132
|
+
top_k: int = 10,
|
|
133
|
+
filters: dict[str, Any] | None = None,
|
|
134
|
+
hybrid: SearchHybridConfig | dict[str, Any] | None = None,
|
|
135
|
+
rerank: SearchRerankConfig | dict[str, Any] | None = None,
|
|
136
|
+
return_config: SearchReturnConfig | dict[str, Any] | None = None,
|
|
137
|
+
generation: SearchGenerationConfig | dict[str, Any] | None = None,
|
|
138
|
+
request_options: RequestOptions | None = None,
|
|
139
|
+
) -> SearchGenerateResponse:
|
|
140
|
+
"""Search a corpus and generate an LLM answer grounded in the results.
|
|
141
|
+
|
|
142
|
+
Combines retrieval with LLM generation (RAG) in a single call.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
corpus_id: The corpus to search.
|
|
146
|
+
query: The search query text.
|
|
147
|
+
top_k: Maximum number of retrieval results fed to the generator.
|
|
148
|
+
filters: Optional metadata filters to narrow retrieval results.
|
|
149
|
+
hybrid: Hybrid search configuration (dense/sparse weighting).
|
|
150
|
+
rerank: Reranking configuration applied after initial retrieval.
|
|
151
|
+
return_config: Controls which fields are included in the
|
|
152
|
+
retrieval results.
|
|
153
|
+
generation: LLM generation settings (model, temperature,
|
|
154
|
+
system prompt, etc.).
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
The generated answer together with the supporting retrieval
|
|
158
|
+
results.
|
|
159
|
+
|
|
160
|
+
Raises:
|
|
161
|
+
NotFoundError: If the corpus does not exist.
|
|
162
|
+
Knowledge2Error: If the API request fails.
|
|
163
|
+
"""
|
|
164
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
165
|
+
payload: dict[str, Any] = {"query": query, "top_k": top_k}
|
|
166
|
+
if filters is not None:
|
|
167
|
+
payload["filters"] = filters
|
|
168
|
+
if hybrid is not None:
|
|
169
|
+
payload["hybrid"] = hybrid
|
|
170
|
+
if rerank is not None:
|
|
171
|
+
payload["rerank"] = rerank
|
|
172
|
+
if return_config is not None:
|
|
173
|
+
payload["return"] = return_config
|
|
174
|
+
if generation is not None:
|
|
175
|
+
payload["generation"] = generation
|
|
176
|
+
data = self._request(
|
|
177
|
+
"POST",
|
|
178
|
+
f"/v1/corpora/{corpus_id}/search:generate",
|
|
179
|
+
json=payload,
|
|
180
|
+
request_options=request_options,
|
|
181
|
+
)
|
|
182
|
+
return self._maybe_validate(data, "SearchGenerateResponse")
|
|
183
|
+
|
|
184
|
+
def embeddings(
|
|
185
|
+
self,
|
|
186
|
+
model: str,
|
|
187
|
+
inputs: list[str],
|
|
188
|
+
embed_type: str = "query",
|
|
189
|
+
request_options: RequestOptions | None = None,
|
|
190
|
+
) -> EmbeddingsResponse:
|
|
191
|
+
"""Generate vector embeddings for the given texts.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
model: Name or ID of the embedding model to use.
|
|
195
|
+
inputs: List of text strings to embed.
|
|
196
|
+
embed_type: Embedding type — ``"query"`` for search queries
|
|
197
|
+
or ``"document"`` for corpus documents.
|
|
198
|
+
|
|
199
|
+
Returns:
|
|
200
|
+
Embedding vectors for each input text.
|
|
201
|
+
|
|
202
|
+
Raises:
|
|
203
|
+
Knowledge2Error: If the API request fails.
|
|
204
|
+
"""
|
|
205
|
+
payload = {"model": model, "input": inputs, "type": embed_type}
|
|
206
|
+
data = self._request(
|
|
207
|
+
"POST", "/v1/embeddings", json=payload, request_options=request_options
|
|
208
|
+
)
|
|
209
|
+
return self._maybe_validate(data, "EmbeddingsResponse")
|
|
210
|
+
|
|
211
|
+
def list_embedding_models(
|
|
212
|
+
self,
|
|
213
|
+
request_options: RequestOptions | None = None,
|
|
214
|
+
) -> EmbeddingModelListResponse:
|
|
215
|
+
"""List available embedding models.
|
|
216
|
+
|
|
217
|
+
Returns the set of embedding models that can be used with the
|
|
218
|
+
``embeddings`` method, indicating which model is the default.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
The list of available embedding models with default flag.
|
|
222
|
+
|
|
223
|
+
Raises:
|
|
224
|
+
Knowledge2Error: If the API request fails.
|
|
225
|
+
|
|
226
|
+
Example:
|
|
227
|
+
>>> resp = client.list_embedding_models()
|
|
228
|
+
>>> for m in resp["models"]:
|
|
229
|
+
... print(m["model_name"], m["is_default"])
|
|
230
|
+
"""
|
|
231
|
+
data = self._request("GET", "/v1/embeddings/models", request_options=request_options)
|
|
232
|
+
return self._maybe_validate(data, "EmbeddingModelListResponse")
|
|
233
|
+
|
|
234
|
+
def create_feedback(
|
|
235
|
+
self,
|
|
236
|
+
corpus_id: str,
|
|
237
|
+
query: str,
|
|
238
|
+
*,
|
|
239
|
+
clicked_chunk_ids: list[str] | None = None,
|
|
240
|
+
rating: int | None = None,
|
|
241
|
+
abstained: bool = False,
|
|
242
|
+
request_options: RequestOptions | None = None,
|
|
243
|
+
) -> FeedbackResponse:
|
|
244
|
+
"""Submit relevance feedback for a search query.
|
|
245
|
+
|
|
246
|
+
Feedback is used to improve training data and evaluate retrieval
|
|
247
|
+
quality.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
corpus_id: The corpus the query was executed against.
|
|
251
|
+
query: The original search query text.
|
|
252
|
+
clicked_chunk_ids: IDs of chunks the user found relevant.
|
|
253
|
+
rating: Overall relevance rating for the result set.
|
|
254
|
+
abstained: If ``True``, indicates the user chose not to
|
|
255
|
+
rate the results.
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
Confirmation that the feedback was recorded.
|
|
259
|
+
|
|
260
|
+
Raises:
|
|
261
|
+
NotFoundError: If the corpus does not exist.
|
|
262
|
+
Knowledge2Error: If the API request fails.
|
|
263
|
+
"""
|
|
264
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
265
|
+
payload: dict[str, Any] = {
|
|
266
|
+
"query": query,
|
|
267
|
+
"clicked_chunk_ids": clicked_chunk_ids,
|
|
268
|
+
"rating": rating,
|
|
269
|
+
"abstained": abstained,
|
|
270
|
+
}
|
|
271
|
+
data = self._request(
|
|
272
|
+
"POST",
|
|
273
|
+
f"/v1/corpora/{corpus_id}/feedback",
|
|
274
|
+
json=payload,
|
|
275
|
+
request_options=request_options,
|
|
276
|
+
)
|
|
277
|
+
return self._maybe_validate(data, "FeedbackResponse")
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
"""Training and tuning resource mixin for the Knowledge2 SDK."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from sdk._paging import Page, SyncPager
|
|
8
|
+
from sdk._request_options import RequestOptions
|
|
9
|
+
from sdk._validation import require_str
|
|
10
|
+
from sdk.resources._mixin_base import RequesterMixin
|
|
11
|
+
from sdk.types import (
|
|
12
|
+
CancelTuningRunResponse,
|
|
13
|
+
EvalRunDetailResponse,
|
|
14
|
+
PromoteResponse,
|
|
15
|
+
TrainingDataBuildResponse,
|
|
16
|
+
TuningRunBuildResponse,
|
|
17
|
+
TuningRunDetailResponse,
|
|
18
|
+
TuningRunLogsResponse,
|
|
19
|
+
TuningRunResponse,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class TrainingMixin(RequesterMixin):
|
|
24
|
+
def build_training_data(
|
|
25
|
+
self,
|
|
26
|
+
corpus_id: str,
|
|
27
|
+
idempotency_key: str | None = None,
|
|
28
|
+
request_options: RequestOptions | None = None,
|
|
29
|
+
) -> TrainingDataBuildResponse:
|
|
30
|
+
"""Trigger a training data build job for a corpus.
|
|
31
|
+
|
|
32
|
+
Generates query-document pairs from the corpus content for use
|
|
33
|
+
in model tuning.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
corpus_id: The corpus to build training data from.
|
|
37
|
+
idempotency_key: Optional idempotency key to prevent
|
|
38
|
+
duplicate builds.
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
The training data build response, including the background
|
|
42
|
+
job ID.
|
|
43
|
+
|
|
44
|
+
Raises:
|
|
45
|
+
NotFoundError: If the corpus does not exist.
|
|
46
|
+
ConflictError: If a duplicate idempotency key is detected.
|
|
47
|
+
Knowledge2Error: If the API request fails.
|
|
48
|
+
"""
|
|
49
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
50
|
+
headers = self._idempotency_headers(idempotency_key)
|
|
51
|
+
data = self._request(
|
|
52
|
+
"POST",
|
|
53
|
+
f"/v1/corpora/{corpus_id}/training-data:build",
|
|
54
|
+
json={},
|
|
55
|
+
headers=headers,
|
|
56
|
+
request_options=request_options,
|
|
57
|
+
)
|
|
58
|
+
return self._maybe_validate(data, "TrainingDataBuildResponse")
|
|
59
|
+
|
|
60
|
+
def list_training_data(
|
|
61
|
+
self,
|
|
62
|
+
corpus_id: str,
|
|
63
|
+
limit: int = 100,
|
|
64
|
+
offset: int = 0,
|
|
65
|
+
request_options: RequestOptions | None = None,
|
|
66
|
+
) -> Page[dict[str, Any]]:
|
|
67
|
+
"""List training datasets generated for a corpus.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
corpus_id: The corpus whose training data to list.
|
|
71
|
+
limit: Maximum number of datasets to return per page.
|
|
72
|
+
offset: Number of datasets to skip for pagination.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
A Page containing training dataset records with pagination metadata.
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
Knowledge2Error: If the API request fails.
|
|
79
|
+
"""
|
|
80
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
81
|
+
return self._list_page(
|
|
82
|
+
"GET",
|
|
83
|
+
f"/v1/corpora/{corpus_id}/training-data",
|
|
84
|
+
items_key="datasets",
|
|
85
|
+
limit=limit,
|
|
86
|
+
offset=offset,
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def iter_training_data(
|
|
90
|
+
self,
|
|
91
|
+
corpus_id: str,
|
|
92
|
+
*,
|
|
93
|
+
limit: int = 100,
|
|
94
|
+
request_options: RequestOptions | None = None,
|
|
95
|
+
) -> SyncPager[dict[str, Any]]:
|
|
96
|
+
"""Iterate over training data, automatically paginating.
|
|
97
|
+
|
|
98
|
+
Args:
|
|
99
|
+
corpus_id: The corpus whose training data to iterate.
|
|
100
|
+
limit: Page size used for each underlying API request.
|
|
101
|
+
|
|
102
|
+
Yields:
|
|
103
|
+
Individual training dataset dicts.
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
Knowledge2Error: If any underlying API request fails.
|
|
107
|
+
"""
|
|
108
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
109
|
+
return self._paginate(
|
|
110
|
+
"GET",
|
|
111
|
+
f"/v1/corpora/{corpus_id}/training-data",
|
|
112
|
+
items_key="datasets",
|
|
113
|
+
limit=limit,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def list_tuning_runs(
|
|
117
|
+
self,
|
|
118
|
+
corpus_id: str,
|
|
119
|
+
limit: int = 100,
|
|
120
|
+
offset: int = 0,
|
|
121
|
+
request_options: RequestOptions | None = None,
|
|
122
|
+
) -> Page[dict[str, Any]]:
|
|
123
|
+
"""List tuning runs for a corpus.
|
|
124
|
+
|
|
125
|
+
Args:
|
|
126
|
+
corpus_id: The corpus whose tuning runs to list.
|
|
127
|
+
limit: Maximum number of tuning runs to return per page.
|
|
128
|
+
offset: Number of tuning runs to skip for pagination.
|
|
129
|
+
|
|
130
|
+
Returns:
|
|
131
|
+
A Page containing tuning run records with pagination metadata.
|
|
132
|
+
|
|
133
|
+
Raises:
|
|
134
|
+
Knowledge2Error: If the API request fails.
|
|
135
|
+
"""
|
|
136
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
137
|
+
return self._list_page(
|
|
138
|
+
"GET",
|
|
139
|
+
f"/v1/corpora/{corpus_id}/tuning-runs",
|
|
140
|
+
items_key="runs",
|
|
141
|
+
limit=limit,
|
|
142
|
+
offset=offset,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def iter_tuning_runs(
|
|
146
|
+
self,
|
|
147
|
+
corpus_id: str,
|
|
148
|
+
*,
|
|
149
|
+
limit: int = 100,
|
|
150
|
+
request_options: RequestOptions | None = None,
|
|
151
|
+
) -> SyncPager[dict[str, Any]]:
|
|
152
|
+
"""Iterate over tuning runs, automatically paginating.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
corpus_id: The corpus whose tuning runs to iterate.
|
|
156
|
+
limit: Page size used for each underlying API request.
|
|
157
|
+
|
|
158
|
+
Yields:
|
|
159
|
+
Individual tuning run dicts.
|
|
160
|
+
|
|
161
|
+
Raises:
|
|
162
|
+
Knowledge2Error: If any underlying API request fails.
|
|
163
|
+
"""
|
|
164
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
165
|
+
return self._paginate(
|
|
166
|
+
"GET",
|
|
167
|
+
f"/v1/corpora/{corpus_id}/tuning-runs",
|
|
168
|
+
items_key="runs",
|
|
169
|
+
limit=limit,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
def create_tuning_run(
|
|
173
|
+
self,
|
|
174
|
+
corpus_id: str,
|
|
175
|
+
idempotency_key: str | None = None,
|
|
176
|
+
*,
|
|
177
|
+
request_options: RequestOptions | None = None,
|
|
178
|
+
) -> TuningRunResponse:
|
|
179
|
+
"""Create a tuning run for the corpus.
|
|
180
|
+
|
|
181
|
+
Args:
|
|
182
|
+
corpus_id: The corpus to tune.
|
|
183
|
+
idempotency_key: Optional idempotency key.
|
|
184
|
+
"""
|
|
185
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
186
|
+
headers = self._idempotency_headers(idempotency_key)
|
|
187
|
+
data = self._request(
|
|
188
|
+
"POST",
|
|
189
|
+
f"/v1/corpora/{corpus_id}/tuning-runs",
|
|
190
|
+
json={},
|
|
191
|
+
headers=headers,
|
|
192
|
+
request_options=request_options,
|
|
193
|
+
)
|
|
194
|
+
return self._maybe_validate(data, "TuningRunResponse")
|
|
195
|
+
|
|
196
|
+
def build_and_start_tuning_run(
|
|
197
|
+
self,
|
|
198
|
+
corpus_id: str,
|
|
199
|
+
idempotency_key: str | None = None,
|
|
200
|
+
*,
|
|
201
|
+
wait: bool = True,
|
|
202
|
+
poll_s: int = 5,
|
|
203
|
+
request_options: RequestOptions | None = None,
|
|
204
|
+
) -> TuningRunBuildResponse:
|
|
205
|
+
"""Build training data and start a tuning run in one step.
|
|
206
|
+
|
|
207
|
+
This is a convenience method that combines training data
|
|
208
|
+
generation and tuning run creation into a single call.
|
|
209
|
+
|
|
210
|
+
Args:
|
|
211
|
+
corpus_id: The corpus to tune.
|
|
212
|
+
idempotency_key: Optional idempotency key to prevent
|
|
213
|
+
duplicate runs.
|
|
214
|
+
wait: If ``True`` (default), block until the build job
|
|
215
|
+
completes.
|
|
216
|
+
poll_s: Polling interval in seconds when *wait* is ``True``.
|
|
217
|
+
|
|
218
|
+
Returns:
|
|
219
|
+
The tuning run build response, including the background
|
|
220
|
+
job ID.
|
|
221
|
+
|
|
222
|
+
Raises:
|
|
223
|
+
NotFoundError: If the corpus does not exist.
|
|
224
|
+
ConflictError: If a duplicate idempotency key is detected.
|
|
225
|
+
Knowledge2Error: If the API request fails.
|
|
226
|
+
"""
|
|
227
|
+
corpus_id = require_str(corpus_id, "corpus_id")
|
|
228
|
+
headers = self._idempotency_headers(idempotency_key)
|
|
229
|
+
data = self._request(
|
|
230
|
+
"POST",
|
|
231
|
+
f"/v1/corpora/{corpus_id}/tuning-runs:build",
|
|
232
|
+
json={},
|
|
233
|
+
headers=headers,
|
|
234
|
+
request_options=request_options,
|
|
235
|
+
)
|
|
236
|
+
if wait:
|
|
237
|
+
job_id = data.get("build_job_id") or data.get("job_id")
|
|
238
|
+
if job_id:
|
|
239
|
+
self._wait_for_job(job_id, poll_s=poll_s)
|
|
240
|
+
return self._maybe_validate(data, "TuningRunBuildResponse")
|
|
241
|
+
|
|
242
|
+
def get_tuning_run(
|
|
243
|
+
self,
|
|
244
|
+
run_id: str,
|
|
245
|
+
request_options: RequestOptions | None = None,
|
|
246
|
+
) -> TuningRunDetailResponse:
|
|
247
|
+
"""Retrieve details of a tuning run.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
run_id: Unique identifier of the tuning run.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
Detailed tuning run information including status, metrics,
|
|
254
|
+
and configuration.
|
|
255
|
+
|
|
256
|
+
Raises:
|
|
257
|
+
NotFoundError: If the tuning run does not exist.
|
|
258
|
+
Knowledge2Error: If the API request fails.
|
|
259
|
+
"""
|
|
260
|
+
run_id = require_str(run_id, "run_id")
|
|
261
|
+
data = self._request("GET", f"/v1/tuning-runs/{run_id}", request_options=request_options)
|
|
262
|
+
return self._maybe_validate(data, "TuningRunDetailResponse")
|
|
263
|
+
|
|
264
|
+
def get_tuning_run_logs(
|
|
265
|
+
self,
|
|
266
|
+
run_id: str,
|
|
267
|
+
tail: int = 200,
|
|
268
|
+
request_options: RequestOptions | None = None,
|
|
269
|
+
) -> TuningRunLogsResponse:
|
|
270
|
+
"""Retrieve log output from a tuning run.
|
|
271
|
+
|
|
272
|
+
Args:
|
|
273
|
+
run_id: Unique identifier of the tuning run.
|
|
274
|
+
tail: Number of most recent log lines to return.
|
|
275
|
+
|
|
276
|
+
Returns:
|
|
277
|
+
The requested log lines from the tuning run.
|
|
278
|
+
|
|
279
|
+
Raises:
|
|
280
|
+
NotFoundError: If the tuning run does not exist.
|
|
281
|
+
Knowledge2Error: If the API request fails.
|
|
282
|
+
"""
|
|
283
|
+
run_id = require_str(run_id, "run_id")
|
|
284
|
+
data = self._request(
|
|
285
|
+
"GET",
|
|
286
|
+
f"/v1/tuning-runs/{run_id}/logs",
|
|
287
|
+
params={"tail": tail},
|
|
288
|
+
request_options=request_options,
|
|
289
|
+
)
|
|
290
|
+
return self._maybe_validate(data, "TuningRunLogsResponse")
|
|
291
|
+
|
|
292
|
+
def cancel_tuning_run(
|
|
293
|
+
self,
|
|
294
|
+
run_id: str,
|
|
295
|
+
request_options: RequestOptions | None = None,
|
|
296
|
+
) -> CancelTuningRunResponse:
|
|
297
|
+
"""Cancel a running or pending tuning run.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
run_id: Unique identifier of the tuning run to cancel.
|
|
301
|
+
|
|
302
|
+
Returns:
|
|
303
|
+
Confirmation of the cancellation.
|
|
304
|
+
|
|
305
|
+
Raises:
|
|
306
|
+
NotFoundError: If the tuning run does not exist.
|
|
307
|
+
Knowledge2Error: If the API request fails.
|
|
308
|
+
"""
|
|
309
|
+
run_id = require_str(run_id, "run_id")
|
|
310
|
+
data = self._request(
|
|
311
|
+
"POST", f"/v1/tuning-runs/{run_id}:cancel", request_options=request_options
|
|
312
|
+
)
|
|
313
|
+
return self._maybe_validate(data, "CancelTuningRunResponse")
|
|
314
|
+
|
|
315
|
+
def promote_tuning_run(
|
|
316
|
+
self,
|
|
317
|
+
run_id: str,
|
|
318
|
+
request_options: RequestOptions | None = None,
|
|
319
|
+
) -> PromoteResponse:
|
|
320
|
+
"""Promote a completed tuning run to create a deployable model.
|
|
321
|
+
|
|
322
|
+
Args:
|
|
323
|
+
run_id: Unique identifier of the tuning run to promote.
|
|
324
|
+
|
|
325
|
+
Returns:
|
|
326
|
+
The promotion result, including the created model ID.
|
|
327
|
+
|
|
328
|
+
Raises:
|
|
329
|
+
NotFoundError: If the tuning run does not exist.
|
|
330
|
+
Knowledge2Error: If the API request fails.
|
|
331
|
+
"""
|
|
332
|
+
run_id = require_str(run_id, "run_id")
|
|
333
|
+
data = self._request(
|
|
334
|
+
"POST", f"/v1/tuning-runs/{run_id}:promote", request_options=request_options
|
|
335
|
+
)
|
|
336
|
+
return self._maybe_validate(data, "PromoteResponse")
|
|
337
|
+
|
|
338
|
+
def get_eval_run(
|
|
339
|
+
self,
|
|
340
|
+
eval_id: str,
|
|
341
|
+
request_options: RequestOptions | None = None,
|
|
342
|
+
) -> EvalRunDetailResponse:
|
|
343
|
+
"""Retrieve details of an evaluation run.
|
|
344
|
+
|
|
345
|
+
Args:
|
|
346
|
+
eval_id: Unique identifier of the evaluation run.
|
|
347
|
+
|
|
348
|
+
Returns:
|
|
349
|
+
Detailed evaluation run information including metrics and
|
|
350
|
+
status.
|
|
351
|
+
|
|
352
|
+
Raises:
|
|
353
|
+
NotFoundError: If the evaluation run does not exist.
|
|
354
|
+
Knowledge2Error: If the API request fails.
|
|
355
|
+
"""
|
|
356
|
+
eval_id = require_str(eval_id, "eval_id")
|
|
357
|
+
data = self._request("GET", f"/v1/eval-runs/{eval_id}", request_options=request_options)
|
|
358
|
+
return self._maybe_validate(data, "EvalRunDetailResponse")
|