seekrai 0.4.1__py3-none-any.whl → 0.4.4__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.
seekrai/client.py CHANGED
@@ -19,8 +19,10 @@ class SeekrFlow:
19
19
  models: resources.Models
20
20
  fine_tuning: resources.FineTuning
21
21
  alignment: resources.Alignment
22
+ ingestion: resources.Ingestion
22
23
  projects: resources.Projects
23
24
  deployments: resources.Deployments
25
+ agents: resources.Agents
24
26
 
25
27
  # client options
26
28
  client: SeekrFlowClient
@@ -81,8 +83,10 @@ class SeekrFlow:
81
83
  self.models = resources.Models(self.client)
82
84
  self.fine_tuning = resources.FineTuning(self.client)
83
85
  self.alignment = resources.Alignment(self.client)
86
+ self.ingestion = resources.Ingestion(self.client)
84
87
  self.projects = resources.Projects(self.client)
85
88
  self.deployments = resources.Deployments(self.client)
89
+ self.agents = resources.Agents(self.client)
86
90
 
87
91
 
88
92
  class AsyncSeekrFlow:
@@ -94,8 +98,10 @@ class AsyncSeekrFlow:
94
98
  models: resources.AsyncModels
95
99
  fine_tuning: resources.AsyncFineTuning
96
100
  alignment: resources.AsyncAlignment
101
+ ingestion: resources.AsyncIngestion
97
102
  projects: resources.AsyncProjects
98
103
  deployments: resources.AsyncDeployments
104
+ agents: resources.Agents
99
105
 
100
106
  # client options
101
107
  client: SeekrFlowClient
@@ -156,8 +162,10 @@ class AsyncSeekrFlow:
156
162
  self.models = resources.AsyncModels(self.client)
157
163
  self.fine_tuning = resources.AsyncFineTuning(self.client)
158
164
  self.alignment = resources.AsyncAlignment(self.client)
165
+ self.ingestion = resources.AsyncIngestion(self.client)
159
166
  self.projects = resources.AsyncProjects(self.client)
160
167
  self.deployments = resources.AsyncDeployments(self.client)
168
+ self.agents = resources.Agents(self.client)
161
169
 
162
170
 
163
171
  Client = SeekrFlow
seekrai/filemanager.py CHANGED
@@ -192,7 +192,7 @@ class DownloadManager:
192
192
  method="GET",
193
193
  url=url,
194
194
  ),
195
- stream=True,
195
+ stream=False,
196
196
  )
197
197
 
198
198
  try:
@@ -221,9 +221,10 @@ class DownloadManager:
221
221
  num_bytes_downloaded = response.num_bytes_downloaded
222
222
 
223
223
  # Raise exception if remote file size does not match downloaded file size
224
- if os.stat(temp_file.name).st_size != file_size:
224
+ temp_file_size = os.stat(temp_file.name).st_size
225
+ if temp_file_size != file_size:
225
226
  DownloadError(
226
- f"Downloaded file size `{pbar.n}` bytes does not match "
227
+ f"Downloaded file size `{temp_file_size}` bytes does not match "
227
228
  f"remote file size `{file_size}` bytes."
228
229
  )
229
230
 
@@ -340,3 +341,92 @@ class UploadManager:
340
341
  assert isinstance(response, SeekrFlowResponse)
341
342
 
342
343
  return FileResponse(**response.data)
344
+
345
+ def bulk_upload(
346
+ self,
347
+ url: str,
348
+ files: list[Path],
349
+ *,
350
+ purpose: FilePurpose,
351
+ redirect: bool = False,
352
+ ) -> list[FileResponse]:
353
+ """
354
+ Upload multiple files in a bulk request.
355
+
356
+ Args:
357
+ url: API endpoint to upload to
358
+ files: List of file paths to upload
359
+ purpose: The purpose of the files
360
+ redirect: Whether to redirect after upload
361
+
362
+ Returns:
363
+ List of FileResponse objects for each uploaded file
364
+ """
365
+ requestor = api_requestor.APIRequestor(
366
+ client=self._client,
367
+ )
368
+
369
+ # Prepare files for multipart form upload
370
+ # Format needs to be a list of tuples: [('files', (filename, file_stream)), ...]
371
+ files_tuples = []
372
+ file_streams = []
373
+ progress_bars = []
374
+
375
+ try:
376
+ for file_path in files:
377
+ file_size = os.stat(file_path.as_posix()).st_size
378
+
379
+ # Create progress bar
380
+ progress_bar = tqdm(
381
+ total=file_size,
382
+ unit="B",
383
+ unit_scale=True,
384
+ desc=f"Uploading file {file_path.name}",
385
+ disable=bool(DISABLE_TQDM),
386
+ )
387
+ progress_bars.append(progress_bar)
388
+
389
+ # Open file and track for cleanup
390
+ file_stream = file_path.open("rb")
391
+ file_streams.append(file_stream)
392
+
393
+ # Create wrapper for progress tracking
394
+ reader_wrapper = CallbackIOWrapper(
395
+ progress_bar.update, file_stream, "read"
396
+ )
397
+
398
+ # Add to files list as a tuple
399
+ files_tuples.append(("files", (file_path.name, reader_wrapper)))
400
+
401
+ # Make the request
402
+ response, _, _ = requestor.request(
403
+ options=SeekrFlowRequest(
404
+ method="PUT",
405
+ url=url,
406
+ files=files_tuples, # Pass as a list of tuples (field_name, (filename, file_stream))
407
+ params={"purpose": purpose.value},
408
+ allow_redirects=redirect,
409
+ ),
410
+ stream=False,
411
+ )
412
+
413
+ assert isinstance(response, SeekrFlowResponse)
414
+
415
+ # Parse the response
416
+ if isinstance(response.data, list):
417
+ file_responses = [
418
+ FileResponse(**file_data) for file_data in response.data
419
+ ]
420
+ else:
421
+ # Handle case where response might be a single object
422
+ file_responses = [FileResponse(**response.data)]
423
+
424
+ return file_responses
425
+
426
+ finally:
427
+ # Clean up resources
428
+ for file_stream in file_streams:
429
+ file_stream.close()
430
+
431
+ for progress_bar in progress_bars:
432
+ progress_bar.close()
@@ -1,3 +1,4 @@
1
+ from seekrai.resources.agents import Agents
1
2
  from seekrai.resources.alignment import Alignment, AsyncAlignment
2
3
  from seekrai.resources.chat import AsyncChat, Chat
3
4
  from seekrai.resources.completions import AsyncCompletions, Completions
@@ -6,6 +7,7 @@ from seekrai.resources.embeddings import AsyncEmbeddings, Embeddings
6
7
  from seekrai.resources.files import AsyncFiles, Files
7
8
  from seekrai.resources.finetune import AsyncFineTuning, FineTuning
8
9
  from seekrai.resources.images import AsyncImages, Images
10
+ from seekrai.resources.ingestion import AsyncIngestion, Ingestion
9
11
  from seekrai.resources.models import AsyncModels, Models
10
12
  from seekrai.resources.projects import AsyncProjects, Projects
11
13
 
@@ -25,10 +27,13 @@ __all__ = [
25
27
  "Files",
26
28
  "AsyncImages",
27
29
  "Images",
30
+ "Ingestion",
31
+ "AsyncIngestion",
28
32
  "AsyncModels",
29
33
  "Models",
30
34
  "AsyncProjects",
31
35
  "Projects",
32
36
  "AsyncDeployments",
33
37
  "Deployments",
38
+ "Agents",
34
39
  ]
@@ -0,0 +1,8 @@
1
+ from typing import Any
2
+
3
+ from .agent_inference import AgentInference
4
+
5
+
6
+ class Agents:
7
+ def __init__(self, client: Any) -> None:
8
+ self.agent = AgentInference(client)
@@ -0,0 +1,70 @@
1
+ from typing import Any, Dict, Iterator, Union
2
+
3
+ from seekrai.abstract import api_requestor
4
+ from seekrai.seekrflow_response import SeekrFlowResponse
5
+ from seekrai.types import SeekrFlowRequest
6
+
7
+
8
+ class AgentInference:
9
+ def __init__(self, client: Any) -> None:
10
+ self._client = client
11
+
12
+ def run(
13
+ self,
14
+ agent_id: Union[int, str],
15
+ query: str,
16
+ *,
17
+ stream: bool = False,
18
+ thread_id: Union[str, None] = None,
19
+ headers: Union[Dict[str, str], None] = None,
20
+ **model_settings: Any,
21
+ ) -> Union[Dict[str, Any], Iterator[Dict[str, Any]]]:
22
+ """
23
+ Run an inference call on a deployed agent.
24
+
25
+ Args:
26
+ agent_id (Union[int, str]): The unique identifier of the deployed agent.
27
+ query (str): The user query or prompt.
28
+ stream (bool, optional): Whether to stream the response. Defaults to False.
29
+ thread_id (str, optional): An optional thread identifier.
30
+ headers (dict, optional): Optional HTTP headers to include in the request.
31
+ If provided, these will be merged with default headers.
32
+ **model_settings: Additional parameters (such as temperature, max_tokens, etc).
33
+
34
+ Returns:
35
+ A dictionary with the response (if non-streaming) or an iterator over response chunks.
36
+ """
37
+ payload: Dict[str, Any] = {"prompt": query}
38
+ if thread_id is not None:
39
+ payload["thread_id"] = thread_id
40
+ payload.update(model_settings)
41
+
42
+ default_headers = {}
43
+ if self._client.api_key:
44
+ default_headers["x-api-key"] = self._client.api_key
45
+ if self._client.supplied_headers:
46
+ default_headers.update(self._client.supplied_headers)
47
+
48
+ request_headers = default_headers.copy()
49
+ if headers:
50
+ request_headers.update(headers)
51
+
52
+ requestor = api_requestor.APIRequestor(client=self._client)
53
+ endpoint = f"agents/{agent_id}/run"
54
+
55
+ response, _, _ = requestor.request(
56
+ options=SeekrFlowRequest(
57
+ method="POST",
58
+ url=endpoint,
59
+ params=payload,
60
+ headers=request_headers,
61
+ ),
62
+ stream=stream,
63
+ )
64
+
65
+ if stream:
66
+ assert not isinstance(response, SeekrFlowResponse)
67
+ return (chunk.data for chunk in response)
68
+ else:
69
+ assert isinstance(response, SeekrFlowResponse)
70
+ return response.data
@@ -71,6 +71,56 @@ class Files:
71
71
 
72
72
  return file_response
73
73
 
74
+ def bulk_upload(
75
+ self,
76
+ files: list[Path | str],
77
+ *,
78
+ purpose: FilePurpose | str = FilePurpose.FineTune,
79
+ ) -> list[FileResponse]:
80
+ """
81
+ Upload multiple files in bulk.
82
+
83
+ Args:
84
+ files: List of file paths to upload
85
+ purpose: The purpose of the files (defaults to FineTune)
86
+
87
+ Returns:
88
+ List of FileResponse objects for each uploaded file
89
+ """
90
+ if isinstance(purpose, str):
91
+ purpose = FilePurpose(purpose)
92
+
93
+ assert isinstance(purpose, FilePurpose)
94
+
95
+ # Convert string paths to Path objects
96
+ file_paths = [Path(file) if isinstance(file, str) else file for file in files]
97
+
98
+ # Validate all files before uploading (fail fast)
99
+ if purpose == FilePurpose.Alignment:
100
+ for file_path in file_paths:
101
+ file_metadata = self._get_local_file_metadata(file_path)
102
+ suffix = file_metadata["suffix"]
103
+ size = file_metadata["size_bytes"]
104
+ metadata_validation = self.validate_align_file_metadata(
105
+ purpose,
106
+ suffix,
107
+ size,
108
+ )
109
+
110
+ if not metadata_validation.is_valid:
111
+ assert metadata_validation.errors is not None # To appease linter
112
+ raise ValueError(
113
+ f"Alignment file metadata validation failed for {file_path.name}: {metadata_validation.errors}"
114
+ )
115
+
116
+ # Upload the files to s3
117
+ upload_manager = UploadManager(self._client)
118
+ file_responses = upload_manager.bulk_upload(
119
+ "flow/bulk_files", file_paths, purpose=purpose, redirect=True
120
+ )
121
+
122
+ return file_responses
123
+
74
124
  def list(self) -> FileList:
75
125
  requestor = api_requestor.APIRequestor(
76
126
  client=self._client,
@@ -0,0 +1,179 @@
1
+ from typing import List
2
+
3
+ from seekrai.abstract import api_requestor
4
+ from seekrai.seekrflow_response import SeekrFlowResponse
5
+ from seekrai.types import (
6
+ SeekrFlowClient,
7
+ SeekrFlowRequest,
8
+ )
9
+ from seekrai.types.ingestion import IngestionList, IngestionRequest, IngestionResponse
10
+
11
+
12
+ class Ingestion:
13
+ def __init__(self, client: SeekrFlowClient) -> None:
14
+ self._client = client
15
+
16
+ def ingest(
17
+ self,
18
+ files: List[str],
19
+ ) -> IngestionResponse:
20
+ """
21
+ Start an ingestion job for the specified files.
22
+
23
+ Args:
24
+ files (List[str]): List of file IDs to ingest.
25
+
26
+ Returns:
27
+ IngestionResponse: Object containing information about the created ingestion job.
28
+ """
29
+ requestor = api_requestor.APIRequestor(
30
+ client=self._client,
31
+ )
32
+
33
+ parameter_payload = IngestionRequest(
34
+ files=files,
35
+ ).model_dump()
36
+
37
+ response, _, _ = requestor.request(
38
+ options=SeekrFlowRequest(
39
+ method="POST",
40
+ url="flow/alignment/ingestion",
41
+ params=parameter_payload,
42
+ ),
43
+ stream=False,
44
+ )
45
+
46
+ assert isinstance(response, SeekrFlowResponse)
47
+ return IngestionResponse(**response.data)
48
+
49
+ def list(self) -> IngestionList:
50
+ """
51
+ Lists ingestion job history
52
+
53
+ Returns:
54
+ IngestionList: Object containing a list of ingestion jobs
55
+ """
56
+ requestor = api_requestor.APIRequestor(
57
+ client=self._client,
58
+ )
59
+
60
+ response, _, _ = requestor.request(
61
+ options=SeekrFlowRequest(
62
+ method="GET",
63
+ url="flow/alignment/ingestion",
64
+ ),
65
+ stream=False,
66
+ )
67
+
68
+ assert isinstance(response, SeekrFlowResponse)
69
+ return IngestionList(**response.data)
70
+
71
+ def retrieve(self, id: str) -> IngestionResponse:
72
+ """
73
+ Retrieves ingestion job details
74
+
75
+ Args:
76
+ id (str): Ingestion job ID to retrieve.
77
+
78
+ Returns:
79
+ IngestionResponse: Object containing information about ingestion job.
80
+ """
81
+ requestor = api_requestor.APIRequestor(
82
+ client=self._client,
83
+ )
84
+
85
+ response, _, _ = requestor.request(
86
+ options=SeekrFlowRequest(
87
+ method="GET",
88
+ url=f"flow/alignment/ingestion/{id}",
89
+ ),
90
+ stream=False,
91
+ )
92
+
93
+ assert isinstance(response, SeekrFlowResponse)
94
+ return IngestionResponse(**response.data)
95
+
96
+
97
+ class AsyncIngestion:
98
+ def __init__(self, client: SeekrFlowClient) -> None:
99
+ self._client = client
100
+
101
+ async def ingest(
102
+ self,
103
+ files: List[str],
104
+ ) -> IngestionResponse:
105
+ """
106
+ Start an ingestion job for the specified files asynchronously.
107
+
108
+ Args:
109
+ files (List[str]): List of file IDs to ingest.
110
+
111
+ Returns:
112
+ IngestionResponse: Object containing information about the created ingestion job.
113
+ """
114
+ requestor = api_requestor.APIRequestor(
115
+ client=self._client,
116
+ )
117
+
118
+ parameter_payload = IngestionRequest(
119
+ files=files,
120
+ ).model_dump()
121
+
122
+ response, _, _ = await requestor.arequest(
123
+ options=SeekrFlowRequest(
124
+ method="POST",
125
+ url="flow/alignment/ingestion",
126
+ params=parameter_payload,
127
+ ),
128
+ stream=False,
129
+ )
130
+
131
+ assert isinstance(response, SeekrFlowResponse)
132
+ return IngestionResponse(**response.data)
133
+
134
+ async def list(self) -> IngestionList:
135
+ """
136
+ Lists ingestion job history asynchronously
137
+
138
+ Returns:
139
+ IngestionList: Object containing a list of ingestion jobs
140
+ """
141
+ requestor = api_requestor.APIRequestor(
142
+ client=self._client,
143
+ )
144
+
145
+ response, _, _ = await requestor.arequest(
146
+ options=SeekrFlowRequest(
147
+ method="GET",
148
+ url="flow/alignment/ingestion",
149
+ ),
150
+ stream=False,
151
+ )
152
+
153
+ assert isinstance(response, SeekrFlowResponse)
154
+ return IngestionList(**response.data)
155
+
156
+ async def retrieve(self, id: str) -> IngestionResponse:
157
+ """
158
+ Retrieves ingestion job details asynchronously
159
+
160
+ Args:
161
+ id (str): Ingestion job ID to retrieve.
162
+
163
+ Returns:
164
+ IngestionResponse: Object containing information about ingestion job.
165
+ """
166
+ requestor = api_requestor.APIRequestor(
167
+ client=self._client,
168
+ )
169
+
170
+ response, _, _ = await requestor.arequest(
171
+ options=SeekrFlowRequest(
172
+ method="GET",
173
+ url=f"flow/alignment/ingestion/{id}",
174
+ ),
175
+ stream=False,
176
+ )
177
+
178
+ assert isinstance(response, SeekrFlowResponse)
179
+ return IngestionResponse(**response.data)
seekrai/types/common.py CHANGED
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  from enum import Enum
4
- from typing import Any, Dict, List, Optional
4
+ from typing import Any, Dict, List, Optional, Tuple
5
5
 
6
6
  from pydantic import ConfigDict, Field
7
7
 
@@ -72,6 +72,11 @@ class SeekrFlowRequest(BaseModel):
72
72
  url: str
73
73
  headers: Dict[str, str] | None = None
74
74
  params: Dict[str, Any] | None = None
75
- files: Dict[str, Any] | None = None
75
+ files: (
76
+ Dict[str, Any]
77
+ | List[Tuple[str, Tuple[str, Any, Optional[str]]]]
78
+ | List[Tuple[str, Any]]
79
+ | None
80
+ ) = None
76
81
  allow_redirects: bool = True
77
82
  override_headers: bool = False
@@ -31,6 +31,7 @@ class DeploymentProcessor(str, enum.Enum):
31
31
  GAUDI2 = "GAUDI2"
32
32
  GAUDI3 = "GAUDI3"
33
33
  A100 = "A100"
34
+ A10 = "A10"
34
35
  H100 = "H100"
35
36
  XEON = "XEON"
36
37
  NVIDIA = "NVIDIA" # TODO - this doesnt make sense with A100, etc.
seekrai/types/files.py CHANGED
@@ -35,6 +35,8 @@ class AlignmentFileType(str, Enum):
35
35
  DOC = "doc"
36
36
  DOCX = "docx"
37
37
  PDF = "pdf"
38
+ PPT = "ppt"
39
+ PPTX = "pptx"
38
40
 
39
41
 
40
42
  FileType = Union[TrainingFileType, AlignmentFileType]
seekrai/types/finetune.py CHANGED
@@ -111,6 +111,7 @@ class AcceleratorType(str, Enum):
111
111
  GAUDI2 = "GAUDI2"
112
112
  GAUDI3 = "GAUDI3"
113
113
  A100 = "A100"
114
+ A10 = "A10"
114
115
  H100 = "H100"
115
116
 
116
117
 
@@ -1,4 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ from datetime import datetime
1
4
  from enum import Enum
5
+ from typing import List, Literal
6
+
7
+ from pydantic import Field
8
+
9
+ from seekrai.types.abstract import BaseModel
2
10
 
3
11
 
4
12
  class IngestionJobStatus(Enum):
@@ -6,3 +14,24 @@ class IngestionJobStatus(Enum):
6
14
  RUNNING = "running"
7
15
  COMPLETED = "completed"
8
16
  FAILED = "failed"
17
+
18
+
19
+ class IngestionRequest(BaseModel):
20
+ files: List[str] = Field(
21
+ default=..., description="List of file ids to use for alignment"
22
+ )
23
+ method: str = Field(default="best", description="Method to use for ingestion")
24
+
25
+
26
+ class IngestionResponse(BaseModel):
27
+ id: str = Field(default=..., description="Ingestion job ID")
28
+ created_at: datetime
29
+ status: IngestionJobStatus
30
+ output_files: List[str]
31
+
32
+
33
+ class IngestionList(BaseModel):
34
+ # object type
35
+ object: Literal["list"] | None = None
36
+ # list of fine-tune job objects
37
+ data: List[IngestionResponse] | None = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: seekrai
3
- Version: 0.4.1
3
+ Version: 0.4.4
4
4
  Summary: Python client for SeekrAI
5
5
  Home-page: https://gitlab.cb.ntent.com/ml/seekr-py
6
6
  License: Apache-2.0
@@ -1,20 +1,23 @@
1
1
  seekrai/__init__.py,sha256=HC6iy-IdwqecabH-6a80Lsy9qO2PBToAI0WqEErV41c,935
2
2
  seekrai/abstract/__init__.py,sha256=wNiOTW9TJpUgfCJCG-wAbhhWWH2PtoVpAuL3nxvQGps,56
3
3
  seekrai/abstract/api_requestor.py,sha256=NT41M0_Utfw61bMqibP1PEdIIQmmKWfzj-Y-xk4DNY0,18395
4
- seekrai/client.py,sha256=Yhejl-2a-Uoc8nWi-XxETZT4a4Ou_t_TRLcp0e9APIY,5376
4
+ seekrai/client.py,sha256=kc1mCspDVemqkccbp5Rz8cxT8epPtIpwOjy2AA6DPQ8,5734
5
5
  seekrai/constants.py,sha256=hoR2iF5te5Ydjt_lxIOSGID4vESIakG4F-3xAWdwxaU,1854
6
6
  seekrai/error.py,sha256=rAYL8qEd8INwYMMKvhS-HKeC3QkWL4Wq-zfazFU-zBg,4861
7
- seekrai/filemanager.py,sha256=5tl7fjsLbNy-U1Ko_5iQSdkZ0Bca_bhvR9FhWpaG8FA,9561
8
- seekrai/resources/__init__.py,sha256=-OpvrZp0c_ro_e1G14gjOILtcSfpSOeRZeK8kt41WLo,1014
7
+ seekrai/filemanager.py,sha256=Xd3NogO1ZSQa8yvgpXSOL5jQWqHa2Jpn9fFlsRp5Yz4,12542
8
+ seekrai/resources/__init__.py,sha256=9XE72QV90Z1F7ZAae-H_XY_GnXOoX2MG5rsoTVsmWAg,1177
9
+ seekrai/resources/agents/__init__.py,sha256=duQmOJJQYXE_-lnBbVXcZ5P_v3qKojA54zsCLPm6SGI,173
10
+ seekrai/resources/agents/agent_inference.py,sha256=gqu1qvSlXmMvYXj9pollmPYeqUODum0rf2hN0hr8yxw,2515
9
11
  seekrai/resources/alignment.py,sha256=MMrADpXNZa0eQ-jqfLcP7-fisJXgpRl-03GPdkjkTcc,5951
10
12
  seekrai/resources/chat/__init__.py,sha256=KmtPupgECtEN80NyvcnSmieTAFXhwmVxhMHP0qhspA4,618
11
13
  seekrai/resources/chat/completions.py,sha256=U75hKIDBAX8h5-4aFe20DowO1adqBD6ZRHjPK9EdqqM,11653
12
14
  seekrai/resources/completions.py,sha256=w3La3zPMlN00y-b-tJwLgvZVH-xK_dKC6ktI5Ggn1us,8564
13
15
  seekrai/resources/deployments.py,sha256=HmP7MuxAlLUoQl6z705_d1Y53MDvGgSQXhlgN3DKX2A,6078
14
16
  seekrai/resources/embeddings.py,sha256=3lohUrkdFqzSg8FgS7p4r87jwjE0NXU1PilWv278quk,2705
15
- seekrai/resources/files.py,sha256=16FfJFZJjZ10Q38AHvTwE-CtIPpKA0d4zyB52YN14e4,6876
17
+ seekrai/resources/files.py,sha256=7tEsOuoIb8LtieBZzrO932DyGJ9TRwxiSjjonS2qq3s,8653
16
18
  seekrai/resources/finetune.py,sha256=RInur0DctkPzhJ1rWpXYEAFOfre_qwextKcjJlblkKM,11416
17
19
  seekrai/resources/images.py,sha256=E48lAe7YsZ2WXBHR_qz4SF7P4Y-U7t61m_bWNS91pM0,4802
20
+ seekrai/resources/ingestion.py,sha256=pR1LuZohcUJniv9I0wKu093UJdqsvS8DO3MiIApFMdg,4966
18
21
  seekrai/resources/models.py,sha256=Pdd0S0gZdratWcHJPKNb7LkEdUGjr3xNR06W6GDiyxk,5000
19
22
  seekrai/resources/projects.py,sha256=AWJUeUDSzkbxBksHjJ4a3c83UR62TlMGHutm2NdV6Xk,3790
20
23
  seekrai/seekrflow_response.py,sha256=5RFEQzamDy7sTSDkxSsZQThZ3biNmeCPeHWdrFId5Go,1320
@@ -22,15 +25,15 @@ seekrai/types/__init__.py,sha256=34IvdhaeKDNqA03G0nwta8sptpURzbXeTlqr6mhagnw,253
22
25
  seekrai/types/abstract.py,sha256=TqWFQV_6bPblywfCH-r8FCkXWvPkc9KlJ4QVgyrnaMc,642
23
26
  seekrai/types/alignment.py,sha256=H9rAYsr4rg7uZCgl2tDZjkeq-b_Ov27gljejH8fC26w,1919
24
27
  seekrai/types/chat_completions.py,sha256=xRTHBbDJDbz0HgW042WX3csQDolhjEuO81w0rzFSeBU,3691
25
- seekrai/types/common.py,sha256=OH3l3u-0_5oz1KYrcHMybFESzivDySocYlJAsLSLOWU,1940
28
+ seekrai/types/common.py,sha256=YI1pE-i_lDLU2o6FjoINdIhPXsV9lUl2MeAg2aRtT-M,2062
26
29
  seekrai/types/completions.py,sha256=lm9AFdZR3Xg5AHPkV-qETHikkwMJmkHrLGr5GG-YR-M,2171
27
- seekrai/types/deployments.py,sha256=n7_t7DEeBSC8cDJSjIfvWtcgUql1DaEn89zuGYN_RaI,1744
30
+ seekrai/types/deployments.py,sha256=GdZPDaQgzmk9W1aXxZr9CDxqJRNv7NP0pNvqRV3E4xM,1760
28
31
  seekrai/types/embeddings.py,sha256=OANoLNOs0aceS8NppVvvcNYQbF7-pAOAmcr30pw64OU,749
29
32
  seekrai/types/error.py,sha256=uTKISs9aRC4_6zwirtNkanxepN8KY-SqCq0kNbfZylQ,370
30
- seekrai/types/files.py,sha256=XmtiM6d9i3tnYS-Kii3QpxZJRqemJi2rvLJ32GsECXQ,2602
31
- seekrai/types/finetune.py,sha256=VNuAZx-Lq4Q55hY47obWnFLDr9if93v5Lwr_qcyCtfU,6124
33
+ seekrai/types/files.py,sha256=PN0bugp0DQKzn0DLn18j9ysGZwNaQmgsTiCVnssEO-E,2636
34
+ seekrai/types/finetune.py,sha256=LUqnLv8oPdasd_F1jGx0WRfNvFDxqO3czl9zfxTxXfg,6140
32
35
  seekrai/types/images.py,sha256=Fusj8OhVYFsT8kz636lRGGivLbPXo_ZNgakKwmzJi3U,914
33
- seekrai/types/ingestion.py,sha256=GqDzPjEA_rtiiDKpEmTOXOitZSSKG-JkH1siII5m8oA,152
36
+ seekrai/types/ingestion.py,sha256=uUdKOR4xqSfAXWQOR1UOltSlOnuyAwKVA1Q2a6Yslk8,919
34
37
  seekrai/types/models.py,sha256=1ZfW9WwayApkISRizDntjkWhYNv-wkbrRVIfHn2QuC4,1242
35
38
  seekrai/types/projects.py,sha256=JFgpZdovia8Orcnhp6QkIEAXzyPCfKT_bUiwjxUaHHQ,670
36
39
  seekrai/utils/__init__.py,sha256=dfbiYEc47EBVRkq6C4O9y6tTGuPuV3LbV3__v01Mbds,658
@@ -39,8 +42,8 @@ seekrai/utils/api_helpers.py,sha256=0Y8BblNIr9h_R12zdmhkxgTlxgoRkbq84QNi4nNWGu8,
39
42
  seekrai/utils/files.py,sha256=7ixn_hgV-6pEhYqLyOp-EN0o8c1CzUwJzX9n3PQ5oqo,7164
40
43
  seekrai/utils/tools.py,sha256=jgJTL-dOIouDbEJLdQpQfpXhqaz_poQYS52adyUtBjo,1781
41
44
  seekrai/version.py,sha256=q6iGQVFor8zXiPP5F-3vy9TndOxKv5JXbaNJ2kdOQws,125
42
- seekrai-0.4.1.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
43
- seekrai-0.4.1.dist-info/METADATA,sha256=28ojGXBP-65YoZv0VfwQ__mN76eC_I53aSso7caRz_E,4748
44
- seekrai-0.4.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
45
- seekrai-0.4.1.dist-info/entry_points.txt,sha256=N49yOEGi1sK7Xr13F_rkkcOxQ88suyiMoOmRhUHTZ_U,48
46
- seekrai-0.4.1.dist-info/RECORD,,
45
+ seekrai-0.4.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
46
+ seekrai-0.4.4.dist-info/METADATA,sha256=h-_bV7yFZexgUirnPMEDEzKHro0Yx2MndKlpwfk32f4,4748
47
+ seekrai-0.4.4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
48
+ seekrai-0.4.4.dist-info/entry_points.txt,sha256=N49yOEGi1sK7Xr13F_rkkcOxQ88suyiMoOmRhUHTZ_U,48
49
+ seekrai-0.4.4.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 1.9.0
2
+ Generator: poetry-core 1.8.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any