bios-sdk 0.1.0-dev.1
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.
- package/README.md +292 -0
- package/dist/client.d.ts +57 -0
- package/dist/client.js +181 -0
- package/dist/index.d.ts +63 -0
- package/dist/index.js +80 -0
- package/dist/resources/datasets.d.ts +180 -0
- package/dist/resources/datasets.js +358 -0
- package/dist/resources/gpu-priorities.d.ts +14 -0
- package/dist/resources/gpu-priorities.js +54 -0
- package/dist/resources/gpu.d.ts +60 -0
- package/dist/resources/gpu.js +101 -0
- package/dist/resources/inference.d.ts +82 -0
- package/dist/resources/inference.js +529 -0
- package/dist/resources/models.d.ts +75 -0
- package/dist/resources/models.js +115 -0
- package/dist/resources/training.d.ts +146 -0
- package/dist/resources/training.js +399 -0
- package/dist/resources/wallet.d.ts +44 -0
- package/dist/resources/wallet.js +52 -0
- package/dist/types.d.ts +1466 -0
- package/dist/types.js +4 -0
- package/package.json +49 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import type { HttpClient } from '../client.js';
|
|
2
|
+
import type { Dataset, DatasetListParams, DatasetListResponse, DatasetUploadParams, DatasetPreview, DatasetPreviewParams, DatasetImportHFParams, DatasetRegisterHFParams, DatasetHubSearchParams, DatasetHubPreviewParams, DatasetValidation, DatasetFormatSpecs, DatasetStorageUsage } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Manage training datasets -- upload files, import from HuggingFace,
|
|
5
|
+
* preview contents, and manage storage.
|
|
6
|
+
*/
|
|
7
|
+
export declare class Datasets {
|
|
8
|
+
private readonly _http;
|
|
9
|
+
/** @internal */
|
|
10
|
+
constructor(_http: HttpClient);
|
|
11
|
+
/**
|
|
12
|
+
* List datasets in the current organization/workspace.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* const datasets = await client.datasets.list();
|
|
17
|
+
* console.log(`${datasets.length} datasets`);
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
list(params?: DatasetListParams): Promise<Dataset[]>;
|
|
21
|
+
/** Return one server-driven dataset page with counts and pagination metadata. */
|
|
22
|
+
listPage(params?: DatasetListParams): Promise<DatasetListResponse>;
|
|
23
|
+
/**
|
|
24
|
+
* Get a single dataset by ID.
|
|
25
|
+
*
|
|
26
|
+
* @param id - Dataset ID.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```ts
|
|
30
|
+
* const ds = await client.datasets.get('ds_abc123');
|
|
31
|
+
* console.log(`${ds.name} -- ${ds.row_count} rows`);
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
get(id: string): Promise<Dataset>;
|
|
35
|
+
/**
|
|
36
|
+
* Upload a dataset file from disk.
|
|
37
|
+
*
|
|
38
|
+
* Reads the file using `node:fs` and uploads it via multipart/form-data.
|
|
39
|
+
* Supported formats: JSONL, CSV, Parquet, JSON.
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```ts
|
|
43
|
+
* const uploaded = await client.datasets.upload({
|
|
44
|
+
* filePath: './training_data.jsonl',
|
|
45
|
+
* name: 'My SFT Dataset',
|
|
46
|
+
* });
|
|
47
|
+
* console.log(`Uploaded: ${uploaded.id}`);
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
upload(params: DatasetUploadParams): Promise<Dataset>;
|
|
51
|
+
/**
|
|
52
|
+
* Preview rows from a dataset.
|
|
53
|
+
*
|
|
54
|
+
* @param id - Dataset ID.
|
|
55
|
+
* @param params - Pagination options.
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
* ```ts
|
|
59
|
+
* const preview = await client.datasets.preview('ds_abc123', { page: 1, pageSize: 5 });
|
|
60
|
+
* console.log(preview.samples[0]);
|
|
61
|
+
* console.log(`${preview.total} total preview rows`);
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
preview(id: string, params?: DatasetPreviewParams): Promise<DatasetPreview>;
|
|
65
|
+
/**
|
|
66
|
+
* Delete a dataset.
|
|
67
|
+
*
|
|
68
|
+
* @param id - Dataset ID.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* await client.datasets.delete('ds_abc123');
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
delete(id: string): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Import a dataset from HuggingFace Hub via a connected integration.
|
|
78
|
+
*
|
|
79
|
+
* Requires a HuggingFace integration to be set up. Use
|
|
80
|
+
* `client.integrations.list()` to find available integrations.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const imported = await client.datasets.importFromHuggingFace({
|
|
85
|
+
* repoId: 'databricks/dolly-15k',
|
|
86
|
+
* integrationId: 'int_abc123',
|
|
87
|
+
* name: 'Dolly 15k',
|
|
88
|
+
* });
|
|
89
|
+
* console.log(`Imported: ${imported.id}`);
|
|
90
|
+
* ```
|
|
91
|
+
*/
|
|
92
|
+
importFromHuggingFace(params: DatasetImportHFParams): Promise<Dataset>;
|
|
93
|
+
/**
|
|
94
|
+
* Register a HuggingFace dataset directly (without an integration).
|
|
95
|
+
*
|
|
96
|
+
* @example
|
|
97
|
+
* ```ts
|
|
98
|
+
* const ds = await client.datasets.registerHuggingFace({
|
|
99
|
+
* repo_id: 'databricks/dolly-15k',
|
|
100
|
+
* name: 'Dolly 15k',
|
|
101
|
+
* split: 'train',
|
|
102
|
+
* });
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
registerHuggingFace(params: DatasetRegisterHFParams | Record<string, unknown>): Promise<Dataset>;
|
|
106
|
+
/**
|
|
107
|
+
* Get the processing status of a dataset.
|
|
108
|
+
*
|
|
109
|
+
* @param id - Dataset ID.
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```ts
|
|
113
|
+
* const status = await client.datasets.getStatus('ds_abc123');
|
|
114
|
+
* console.log(status);
|
|
115
|
+
* ```
|
|
116
|
+
*/
|
|
117
|
+
getStatus(id: string): Promise<Record<string, unknown>>;
|
|
118
|
+
/**
|
|
119
|
+
* Validate a dataset file before uploading.
|
|
120
|
+
*
|
|
121
|
+
* @param filePath - Path to the file to validate.
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```ts
|
|
125
|
+
* const result = await client.datasets.validate('./data.jsonl');
|
|
126
|
+
* if (result.format_valid) {
|
|
127
|
+
* console.log(`Valid ${result.detected_format} with ${result.num_samples} rows`);
|
|
128
|
+
* } else {
|
|
129
|
+
* console.error('Errors:', result.validation_errors);
|
|
130
|
+
* }
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
validate(filePath: string): Promise<DatasetValidation>;
|
|
134
|
+
/**
|
|
135
|
+
* Get supported dataset format specifications.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```ts
|
|
139
|
+
* const specs = await client.datasets.getFormatSpecs();
|
|
140
|
+
* for (const spec of specs) {
|
|
141
|
+
* console.log(`${spec.format}: ${spec.extensions.join(', ')}`);
|
|
142
|
+
* }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
getFormatSpecs(): Promise<DatasetFormatSpecs>;
|
|
146
|
+
/**
|
|
147
|
+
* Search public datasets on HuggingFace Hub.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* ```ts
|
|
151
|
+
* const results = await client.datasets.searchHub({ query: 'code instruct' });
|
|
152
|
+
* ```
|
|
153
|
+
*/
|
|
154
|
+
searchHub(params?: DatasetHubSearchParams): Promise<Record<string, unknown>>;
|
|
155
|
+
/**
|
|
156
|
+
* Preview rows from a HuggingFace Hub dataset before importing.
|
|
157
|
+
*
|
|
158
|
+
* @example
|
|
159
|
+
* ```ts
|
|
160
|
+
* const preview = await client.datasets.previewHub({
|
|
161
|
+
* datasetId: 'databricks/dolly-15k',
|
|
162
|
+
* split: 'train',
|
|
163
|
+
* limit: 5,
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
previewHub(params: DatasetHubPreviewParams): Promise<Record<string, unknown>>;
|
|
168
|
+
/**
|
|
169
|
+
* Get storage usage for datasets.
|
|
170
|
+
*
|
|
171
|
+
* @param workspaceId - Optional workspace ID filter.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* const usage = await client.datasets.getStorageUsage();
|
|
176
|
+
* console.log(`${usage.total_bytes} bytes across ${usage.dataset_count} datasets`);
|
|
177
|
+
* ```
|
|
178
|
+
*/
|
|
179
|
+
getStorageUsage(workspaceId?: string): Promise<DatasetStorageUsage>;
|
|
180
|
+
}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
function normalizeDataset(raw) {
|
|
2
|
+
const dataset = { ...raw };
|
|
3
|
+
if (dataset.file_size === undefined && dataset.file_size_bytes !== undefined) {
|
|
4
|
+
dataset.file_size = dataset.file_size_bytes;
|
|
5
|
+
}
|
|
6
|
+
if (dataset.row_count === undefined && dataset.num_samples != null) {
|
|
7
|
+
dataset.row_count = dataset.num_samples;
|
|
8
|
+
}
|
|
9
|
+
if (dataset.column_count === undefined && dataset.num_columns != null) {
|
|
10
|
+
dataset.column_count = dataset.num_columns;
|
|
11
|
+
}
|
|
12
|
+
if (dataset.format === undefined) {
|
|
13
|
+
dataset.format = dataset.file_format || dataset.detected_format || undefined;
|
|
14
|
+
}
|
|
15
|
+
return dataset;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Manage training datasets -- upload files, import from HuggingFace,
|
|
19
|
+
* preview contents, and manage storage.
|
|
20
|
+
*/
|
|
21
|
+
export class Datasets {
|
|
22
|
+
_http;
|
|
23
|
+
/** @internal */
|
|
24
|
+
constructor(_http) {
|
|
25
|
+
this._http = _http;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* List datasets in the current organization/workspace.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* const datasets = await client.datasets.list();
|
|
33
|
+
* console.log(`${datasets.length} datasets`);
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
async list(params = {}) {
|
|
37
|
+
return (await this.listPage(params)).datasets;
|
|
38
|
+
}
|
|
39
|
+
/** Return one server-driven dataset page with counts and pagination metadata. */
|
|
40
|
+
async listPage(params = {}) {
|
|
41
|
+
const q = new URLSearchParams();
|
|
42
|
+
if (params.workspaceId)
|
|
43
|
+
q.set('workspace_id', params.workspaceId);
|
|
44
|
+
if (params.datasetType)
|
|
45
|
+
q.set('dataset_type', params.datasetType);
|
|
46
|
+
if (params.status)
|
|
47
|
+
q.set('status', params.status);
|
|
48
|
+
if (params.query)
|
|
49
|
+
q.set('q', params.query);
|
|
50
|
+
if (params.sort)
|
|
51
|
+
q.set('sort', params.sort);
|
|
52
|
+
if (params.limit !== undefined)
|
|
53
|
+
q.set('limit', String(params.limit));
|
|
54
|
+
if (params.offset !== undefined)
|
|
55
|
+
q.set('offset', String(params.offset));
|
|
56
|
+
const qs = q.toString();
|
|
57
|
+
const raw = await this._http.fetchGet(`/api/datasets${qs ? `?${qs}` : ''}`);
|
|
58
|
+
if (Array.isArray(raw)) {
|
|
59
|
+
return {
|
|
60
|
+
datasets: raw.map(normalizeDataset),
|
|
61
|
+
total: raw.length,
|
|
62
|
+
counts: { all: raw.length, ready: 0, processing: 0, failed: 0 },
|
|
63
|
+
total_samples: 0,
|
|
64
|
+
limit: raw.length,
|
|
65
|
+
offset: 0,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return { ...raw, datasets: (raw.datasets || []).map(normalizeDataset) };
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get a single dataset by ID.
|
|
72
|
+
*
|
|
73
|
+
* @param id - Dataset ID.
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* const ds = await client.datasets.get('ds_abc123');
|
|
78
|
+
* console.log(`${ds.name} -- ${ds.row_count} rows`);
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
async get(id) {
|
|
82
|
+
return normalizeDataset(await this._http.fetchGet(`/api/datasets/${encodeURIComponent(id)}`));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Upload a dataset file from disk.
|
|
86
|
+
*
|
|
87
|
+
* Reads the file using `node:fs` and uploads it via multipart/form-data.
|
|
88
|
+
* Supported formats: JSONL, CSV, Parquet, JSON.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```ts
|
|
92
|
+
* const uploaded = await client.datasets.upload({
|
|
93
|
+
* filePath: './training_data.jsonl',
|
|
94
|
+
* name: 'My SFT Dataset',
|
|
95
|
+
* });
|
|
96
|
+
* console.log(`Uploaded: ${uploaded.id}`);
|
|
97
|
+
* ```
|
|
98
|
+
*/
|
|
99
|
+
async upload(params) {
|
|
100
|
+
let fileData;
|
|
101
|
+
let fileName;
|
|
102
|
+
try {
|
|
103
|
+
const fs = await import('node:fs');
|
|
104
|
+
const path = await import('node:path');
|
|
105
|
+
const buf = fs.readFileSync(params.filePath);
|
|
106
|
+
// Copy into a standalone ArrayBuffer to avoid SharedArrayBuffer type mismatch
|
|
107
|
+
fileData = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
108
|
+
fileName = path.basename(params.filePath);
|
|
109
|
+
}
|
|
110
|
+
catch (err) {
|
|
111
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
112
|
+
throw new Error(`Failed to read file at "${params.filePath}": ${message}`);
|
|
113
|
+
}
|
|
114
|
+
const blob = new Blob([fileData]);
|
|
115
|
+
const formData = new FormData();
|
|
116
|
+
formData.append('file', blob, fileName);
|
|
117
|
+
formData.append('name', params.name);
|
|
118
|
+
if (params.description)
|
|
119
|
+
formData.append('description', params.description);
|
|
120
|
+
const workspaceId = params.workspaceId || this._http.workspaceId;
|
|
121
|
+
if (!workspaceId) {
|
|
122
|
+
throw new Error('BiOS: workspaceId is required for dataset uploads');
|
|
123
|
+
}
|
|
124
|
+
formData.append('workspace_id', workspaceId);
|
|
125
|
+
if (params.format)
|
|
126
|
+
formData.append('format', params.format);
|
|
127
|
+
if (params.maxSamples !== undefined)
|
|
128
|
+
formData.append('max_samples', String(params.maxSamples));
|
|
129
|
+
if (params.columnMapping !== undefined) {
|
|
130
|
+
formData.append('column_mapping', JSON.stringify(params.columnMapping));
|
|
131
|
+
}
|
|
132
|
+
return normalizeDataset(await this._http.fetchUpload('/api/datasets/upload', formData));
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Preview rows from a dataset.
|
|
136
|
+
*
|
|
137
|
+
* @param id - Dataset ID.
|
|
138
|
+
* @param params - Pagination options.
|
|
139
|
+
*
|
|
140
|
+
* @example
|
|
141
|
+
* ```ts
|
|
142
|
+
* const preview = await client.datasets.preview('ds_abc123', { page: 1, pageSize: 5 });
|
|
143
|
+
* console.log(preview.samples[0]);
|
|
144
|
+
* console.log(`${preview.total} total preview rows`);
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
async preview(id, params = {}) {
|
|
148
|
+
const page = params.page ?? 1;
|
|
149
|
+
const pageSize = params.pageSize ?? 10;
|
|
150
|
+
const result = await this._http.fetchGet(`/api/datasets/${encodeURIComponent(id)}/preview?page=${page}&page_size=${pageSize}`);
|
|
151
|
+
return {
|
|
152
|
+
...result,
|
|
153
|
+
samples: result.samples || result.rows || [],
|
|
154
|
+
total: result.total ?? result.total_rows ?? 0,
|
|
155
|
+
total_pages: result.total_pages ?? 0,
|
|
156
|
+
rows: result.samples || result.rows || [],
|
|
157
|
+
total_rows: result.total ?? result.total_rows ?? 0,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Delete a dataset.
|
|
162
|
+
*
|
|
163
|
+
* @param id - Dataset ID.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* await client.datasets.delete('ds_abc123');
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
async delete(id) {
|
|
171
|
+
await this._http.fetchDelete(`/api/datasets/${encodeURIComponent(id)}`);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Import a dataset from HuggingFace Hub via a connected integration.
|
|
175
|
+
*
|
|
176
|
+
* Requires a HuggingFace integration to be set up. Use
|
|
177
|
+
* `client.integrations.list()` to find available integrations.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```ts
|
|
181
|
+
* const imported = await client.datasets.importFromHuggingFace({
|
|
182
|
+
* repoId: 'databricks/dolly-15k',
|
|
183
|
+
* integrationId: 'int_abc123',
|
|
184
|
+
* name: 'Dolly 15k',
|
|
185
|
+
* });
|
|
186
|
+
* console.log(`Imported: ${imported.id}`);
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
async importFromHuggingFace(params) {
|
|
190
|
+
if (!params.integrationId) {
|
|
191
|
+
throw new Error('integrationId is required for importing from HuggingFace');
|
|
192
|
+
}
|
|
193
|
+
return normalizeDataset(await this._http.fetchPost(`/api/datasets/integrations/${encodeURIComponent(params.integrationId)}/import`, {
|
|
194
|
+
dataset_id: params.repoId,
|
|
195
|
+
name: params.name || params.repoId.split('/').pop() || params.repoId,
|
|
196
|
+
subset: params.subset,
|
|
197
|
+
split: params.split,
|
|
198
|
+
max_samples: params.maxSamples,
|
|
199
|
+
sample_strategy: params.sampleStrategy,
|
|
200
|
+
column_mapping: params.columnMapping,
|
|
201
|
+
import_mode: params.importMode,
|
|
202
|
+
}));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Register a HuggingFace dataset directly (without an integration).
|
|
206
|
+
*
|
|
207
|
+
* @example
|
|
208
|
+
* ```ts
|
|
209
|
+
* const ds = await client.datasets.registerHuggingFace({
|
|
210
|
+
* repo_id: 'databricks/dolly-15k',
|
|
211
|
+
* name: 'Dolly 15k',
|
|
212
|
+
* split: 'train',
|
|
213
|
+
* });
|
|
214
|
+
* ```
|
|
215
|
+
*/
|
|
216
|
+
async registerHuggingFace(params) {
|
|
217
|
+
const raw = params;
|
|
218
|
+
const repoId = String(raw.repoId || raw.hf_dataset_id || raw.repo_id || '');
|
|
219
|
+
if (!repoId)
|
|
220
|
+
throw new Error('BiOS: repoId is required');
|
|
221
|
+
const workspaceId = String(raw.workspaceId || raw.workspace_id || '') || this._http.workspaceId;
|
|
222
|
+
if (!workspaceId) {
|
|
223
|
+
throw new Error('BiOS: workspaceId is required to register a HuggingFace dataset');
|
|
224
|
+
}
|
|
225
|
+
const result = await this._http.fetchPost('/api/datasets/register-hf', {
|
|
226
|
+
hf_dataset_id: repoId,
|
|
227
|
+
name: raw.name || repoId.split('/').pop() || repoId,
|
|
228
|
+
workspace_id: workspaceId,
|
|
229
|
+
description: raw.description,
|
|
230
|
+
hf_subset: raw.subset ?? raw.hf_subset,
|
|
231
|
+
hf_split: raw.split ?? raw.hf_split,
|
|
232
|
+
max_samples: raw.maxSamples ?? raw.max_samples,
|
|
233
|
+
sample_strategy: raw.sampleStrategy ?? raw.sample_strategy,
|
|
234
|
+
column_mapping: raw.columnMapping ?? raw.column_mapping,
|
|
235
|
+
import_mode: raw.importMode ?? raw.import_mode,
|
|
236
|
+
});
|
|
237
|
+
return normalizeDataset(result);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get the processing status of a dataset.
|
|
241
|
+
*
|
|
242
|
+
* @param id - Dataset ID.
|
|
243
|
+
*
|
|
244
|
+
* @example
|
|
245
|
+
* ```ts
|
|
246
|
+
* const status = await client.datasets.getStatus('ds_abc123');
|
|
247
|
+
* console.log(status);
|
|
248
|
+
* ```
|
|
249
|
+
*/
|
|
250
|
+
async getStatus(id) {
|
|
251
|
+
return this._http.fetchGet(`/api/datasets/${encodeURIComponent(id)}/status`);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Validate a dataset file before uploading.
|
|
255
|
+
*
|
|
256
|
+
* @param filePath - Path to the file to validate.
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```ts
|
|
260
|
+
* const result = await client.datasets.validate('./data.jsonl');
|
|
261
|
+
* if (result.format_valid) {
|
|
262
|
+
* console.log(`Valid ${result.detected_format} with ${result.num_samples} rows`);
|
|
263
|
+
* } else {
|
|
264
|
+
* console.error('Errors:', result.validation_errors);
|
|
265
|
+
* }
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
async validate(filePath) {
|
|
269
|
+
let fileData;
|
|
270
|
+
let fileName;
|
|
271
|
+
try {
|
|
272
|
+
const fs = await import('node:fs');
|
|
273
|
+
const path = await import('node:path');
|
|
274
|
+
const buf = fs.readFileSync(filePath);
|
|
275
|
+
fileData = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength);
|
|
276
|
+
fileName = path.basename(filePath);
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
280
|
+
throw new Error(`Failed to read file at "${filePath}": ${message}`);
|
|
281
|
+
}
|
|
282
|
+
const blob = new Blob([fileData]);
|
|
283
|
+
const formData = new FormData();
|
|
284
|
+
formData.append('file', blob, fileName);
|
|
285
|
+
return this._http.fetchUpload('/api/datasets/validate', formData);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Get supported dataset format specifications.
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```ts
|
|
292
|
+
* const specs = await client.datasets.getFormatSpecs();
|
|
293
|
+
* for (const spec of specs) {
|
|
294
|
+
* console.log(`${spec.format}: ${spec.extensions.join(', ')}`);
|
|
295
|
+
* }
|
|
296
|
+
* ```
|
|
297
|
+
*/
|
|
298
|
+
async getFormatSpecs() {
|
|
299
|
+
const result = await this._http.fetchGet('/api/datasets/format-specs');
|
|
300
|
+
const wrapped = result;
|
|
301
|
+
return wrapped.formats || result;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Search public datasets on HuggingFace Hub.
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
* ```ts
|
|
308
|
+
* const results = await client.datasets.searchHub({ query: 'code instruct' });
|
|
309
|
+
* ```
|
|
310
|
+
*/
|
|
311
|
+
async searchHub(params = {}) {
|
|
312
|
+
const q = new URLSearchParams();
|
|
313
|
+
if (params.query)
|
|
314
|
+
q.set('q', params.query);
|
|
315
|
+
if (params.page !== undefined)
|
|
316
|
+
q.set('page', String(params.page));
|
|
317
|
+
if (params.sort)
|
|
318
|
+
q.set('sort', params.sort);
|
|
319
|
+
return this._http.fetchGet(`/api/datasets/hub-search?${q}`);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Preview rows from a HuggingFace Hub dataset before importing.
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* const preview = await client.datasets.previewHub({
|
|
327
|
+
* datasetId: 'databricks/dolly-15k',
|
|
328
|
+
* split: 'train',
|
|
329
|
+
* limit: 5,
|
|
330
|
+
* });
|
|
331
|
+
* ```
|
|
332
|
+
*/
|
|
333
|
+
async previewHub(params) {
|
|
334
|
+
const q = new URLSearchParams({ dataset_id: params.datasetId });
|
|
335
|
+
if (params.split)
|
|
336
|
+
q.set('split', params.split);
|
|
337
|
+
if (params.subset)
|
|
338
|
+
q.set('subset', params.subset);
|
|
339
|
+
if (params.limit !== undefined)
|
|
340
|
+
q.set('limit', String(params.limit));
|
|
341
|
+
return this._http.fetchGet(`/api/datasets/hub-preview?${q}`);
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* Get storage usage for datasets.
|
|
345
|
+
*
|
|
346
|
+
* @param workspaceId - Optional workspace ID filter.
|
|
347
|
+
*
|
|
348
|
+
* @example
|
|
349
|
+
* ```ts
|
|
350
|
+
* const usage = await client.datasets.getStorageUsage();
|
|
351
|
+
* console.log(`${usage.total_bytes} bytes across ${usage.dataset_count} datasets`);
|
|
352
|
+
* ```
|
|
353
|
+
*/
|
|
354
|
+
async getStorageUsage(workspaceId) {
|
|
355
|
+
const params = workspaceId ? `?workspace_id=${encodeURIComponent(workspaceId)}` : '';
|
|
356
|
+
return this._http.fetchGet(`/api/datasets/storage-usage${params}`);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GPUChoice } from '../types.js';
|
|
2
|
+
export interface NormalizedGPUPlacement {
|
|
3
|
+
priorities: Array<{
|
|
4
|
+
gpu_type: string;
|
|
5
|
+
gpu_count: number;
|
|
6
|
+
provider?: string;
|
|
7
|
+
region?: string;
|
|
8
|
+
tier: 'secure';
|
|
9
|
+
}> | undefined;
|
|
10
|
+
gpuType: string | undefined;
|
|
11
|
+
gpuCount: number | undefined;
|
|
12
|
+
}
|
|
13
|
+
/** Validate the ranked placement contract shared by training and deployments. */
|
|
14
|
+
export declare function normalizeGPUPlacement(choices: GPUChoice[] | undefined, queueEnabled: boolean, gpuType: string | undefined, gpuCount: number | undefined, queueField: 'queueIfUnavailable' | 'allowCapacityQueue'): NormalizedGPUPlacement;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Validate the ranked placement contract shared by training and deployments. */
|
|
2
|
+
export function normalizeGPUPlacement(choices, queueEnabled, gpuType, gpuCount, queueField) {
|
|
3
|
+
if (choices === undefined) {
|
|
4
|
+
if (queueEnabled) {
|
|
5
|
+
throw new Error(`BiOS: ${queueField}=true requires 3 to 5 gpuPriorities`);
|
|
6
|
+
}
|
|
7
|
+
return { priorities: undefined, gpuType, gpuCount };
|
|
8
|
+
}
|
|
9
|
+
if (!Array.isArray(choices) || choices.length === 0) {
|
|
10
|
+
throw new Error('BiOS: gpuPriorities must contain at least one choice');
|
|
11
|
+
}
|
|
12
|
+
if (choices.length > 5) {
|
|
13
|
+
throw new Error('BiOS: gpuPriorities accepts at most 5 choices');
|
|
14
|
+
}
|
|
15
|
+
if (queueEnabled && choices.length < 3) {
|
|
16
|
+
throw new Error(`BiOS: ${queueField}=true requires 3 to 5 gpuPriorities`);
|
|
17
|
+
}
|
|
18
|
+
if (!queueEnabled && choices.length !== 1) {
|
|
19
|
+
throw new Error(`BiOS: gpuPriorities must contain exactly one choice when ${queueField} is false`);
|
|
20
|
+
}
|
|
21
|
+
const seen = new Set();
|
|
22
|
+
const priorities = choices.map((choice, index) => {
|
|
23
|
+
const choiceType = choice.gpuType?.trim();
|
|
24
|
+
if (!choiceType)
|
|
25
|
+
throw new Error(`BiOS: gpuPriorities[${index}].gpuType is required`);
|
|
26
|
+
if (!Number.isInteger(choice.gpuCount) || choice.gpuCount < 1 || choice.gpuCount > 8) {
|
|
27
|
+
throw new Error(`BiOS: gpuPriorities[${index}].gpuCount must be an integer between 1 and 8`);
|
|
28
|
+
}
|
|
29
|
+
const provider = choice.provider?.trim().toLocaleLowerCase('en-US');
|
|
30
|
+
const region = choice.region?.trim().toLocaleLowerCase('en-US');
|
|
31
|
+
const tier = choice.tier?.trim().toLocaleLowerCase('en-US');
|
|
32
|
+
if (tier && tier !== 'secure')
|
|
33
|
+
throw new Error(`BiOS: gpuPriorities[${index}].tier must be secure`);
|
|
34
|
+
// Dedup key only — provider is emitted below solely when the caller set
|
|
35
|
+
// it. Neutral platform alias default (never a vendor name).
|
|
36
|
+
const key = `${provider || 'bios-cloud'}|${region || 'global'}|${tier || 'secure'}|${choiceType.toLocaleLowerCase('en-US')}`;
|
|
37
|
+
if (seen.has(key))
|
|
38
|
+
throw new Error('BiOS: gpuPriorities provider/region/tier/GPU placements must be distinct');
|
|
39
|
+
seen.add(key);
|
|
40
|
+
return {
|
|
41
|
+
gpu_type: choiceType,
|
|
42
|
+
gpu_count: choice.gpuCount,
|
|
43
|
+
...(provider ? { provider } : {}),
|
|
44
|
+
...(region ? { region } : {}),
|
|
45
|
+
tier: 'secure',
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
const first = priorities[0];
|
|
49
|
+
if ((gpuType !== undefined && gpuType.trim() !== first.gpu_type)
|
|
50
|
+
|| (gpuCount !== undefined && gpuCount !== first.gpu_count)) {
|
|
51
|
+
throw new Error('BiOS: gpuType/gpuCount must match the first gpuPriorities choice');
|
|
52
|
+
}
|
|
53
|
+
return { priorities, gpuType: first.gpu_type, gpuCount: first.gpu_count };
|
|
54
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { HttpClient } from '../client.js';
|
|
2
|
+
import type { GPUPricingResponse, GPUInfo, GPUOptionsParams, GPUOptionsResponse } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* View GPU pricing, availability, and get recommendations for your model.
|
|
5
|
+
*/
|
|
6
|
+
export declare class GPU {
|
|
7
|
+
private readonly _http;
|
|
8
|
+
/** @internal */
|
|
9
|
+
constructor(_http: HttpClient);
|
|
10
|
+
/**
|
|
11
|
+
* Get pricing and availability for all GPU types.
|
|
12
|
+
*
|
|
13
|
+
* Returns the full catalog of GPUs with per-hour pricing, VRAM,
|
|
14
|
+
* and which training methods each supports.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const pricing = await client.gpu.getPricing();
|
|
19
|
+
* for (const gpu of pricing.gpus) {
|
|
20
|
+
* console.log(`${gpu.display_name}: ${gpu.price_display} -- ${gpu.vram_gb}GB VRAM`);
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
getPricing(): Promise<GPUPricingResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* Get authoritative, model-aware training GPU options with live stock,
|
|
27
|
+
* required counts, total prices, and alternatives when nothing is bookable.
|
|
28
|
+
*/
|
|
29
|
+
getOptions(params: GPUOptionsParams): Promise<GPUOptionsResponse>;
|
|
30
|
+
/**
|
|
31
|
+
* Get the recommended GPU configuration for a specific model.
|
|
32
|
+
*
|
|
33
|
+
* Uses the model's parameter count and architecture to suggest
|
|
34
|
+
* the best GPU type and count for training.
|
|
35
|
+
*
|
|
36
|
+
* @param modelId - Full HuggingFace model ID (e.g. "meta-llama/Llama-3.1-8B-Instruct").
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```ts
|
|
40
|
+
* const rec = await client.gpu.getRecommended('meta-llama/Llama-3.1-8B-Instruct');
|
|
41
|
+
* if (rec) {
|
|
42
|
+
* console.log(`Recommended: ${rec.display_name} x${rec.recommended_count}`);
|
|
43
|
+
* }
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
getRecommended(modelId: string): Promise<GPURecommendation | null>;
|
|
47
|
+
}
|
|
48
|
+
/** GPU recommendation with sizing rationale. */
|
|
49
|
+
export interface GPURecommendation extends GPUInfo {
|
|
50
|
+
/** Recommended number of GPUs. */
|
|
51
|
+
recommended_count: number;
|
|
52
|
+
/** Total VRAM across all recommended GPUs. */
|
|
53
|
+
total_vram_gb: number;
|
|
54
|
+
/** Estimated hourly cost in cents for the recommended configuration. */
|
|
55
|
+
estimated_cost_per_hour_cents: number;
|
|
56
|
+
/** Model parameter count in billions. */
|
|
57
|
+
model_params_b: number;
|
|
58
|
+
/** Human-readable recommendation reason. */
|
|
59
|
+
reason: string;
|
|
60
|
+
}
|