@toloka-platform/sdk 0.6.0 → 0.7.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.
Binary file
@@ -1 +1 @@
1
- 4152a6a66243067c73d45dd077a87a1705b645b14e36c558263663f4939006a4 toloka.js.jsc
1
+ 470f83e33807a6eb790be795c23e4eae38d86e524ebf7b217f4c8a846e5295aa toloka.js.jsc
@@ -1 +1 @@
1
- 5dac0697d5d6357e396c06f60b30f99939d2b4cba45130a15effdce678045f48 toloka.js
1
+ 72075dc4b4f418044a760862db47c1874dc9fc17c3075e4df078960f3c3bad44 toloka.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toloka-platform/sdk",
3
- "version": "0.6.0",
3
+ "version": "0.7.1",
4
4
  "private": false,
5
5
  "description": "Build, inspect, and operate Toloka pipeline projects as TypeScript source. The public API may change between minor versions before 1.0.",
6
6
  "license": "Apache-2.0",
@@ -77,6 +77,6 @@
77
77
  "bun": ">=1.4.0"
78
78
  },
79
79
  "tolokaBuild": {
80
- "commit": "4658b9a88d4322ec5c9bc8cedbc0f31e0150a859"
80
+ "commit": "4e86bfc2e063245196b86c4e2f451c842de75a34"
81
81
  }
82
82
  }
@@ -11,8 +11,8 @@
11
11
  "testing",
12
12
  "checks"
13
13
  ],
14
- "version": "0.6.0",
15
- "digest": "c17a1c4f9b3b974ae07859bc3ac7669d98d47d9984e174712f550ef7c3204d63",
14
+ "version": "0.7.1",
15
+ "digest": "23a08f37b1fba9abf57d3eb2a2f7156d241e51bb41cc06bcf3f2ff3f1a9635a0",
16
16
  "files": [
17
17
  "SKILL.md",
18
18
  "references/node-semantics.md",
@@ -29,7 +29,7 @@
29
29
  "bug",
30
30
  "report"
31
31
  ],
32
- "version": "0.6.0",
32
+ "version": "0.7.1",
33
33
  "digest": "70f0bd2c80b32f87896aeb27c363b8a2d37f40e22424f57fe1aad142e125ad67",
34
34
  "files": [
35
35
  "SKILL.md",
@@ -46,7 +46,7 @@
46
46
  "getting-started",
47
47
  "agent"
48
48
  ],
49
- "version": "0.6.0",
49
+ "version": "0.7.1",
50
50
  "digest": "ccf148c682de4e452bb031db95d3933257899006b1766f0fdbc3d15265a63bb9",
51
51
  "files": [
52
52
  "SKILL.md"
@@ -63,8 +63,8 @@
63
63
  "sft",
64
64
  "models"
65
65
  ],
66
- "version": "0.6.0",
67
- "digest": "f9c34569fc344f365c79c86819adffc86c78a2ce74e17ba10755ddefaf71790f",
66
+ "version": "0.7.1",
67
+ "digest": "279c69977eef170dada20b664ee0c30858681e84a2cabb2fdff18b8bb1bdc055",
68
68
  "files": [
69
69
  "SKILL.md"
70
70
  ]
@@ -80,8 +80,8 @@
80
80
  "prompt",
81
81
  "models"
82
82
  ],
83
- "version": "0.6.0",
84
- "digest": "902aee47c952e105a6340ee56bf22e79513e2d45d19a7ffbf58990f277387e34",
83
+ "version": "0.7.1",
84
+ "digest": "4501e480901fc32c26de0314b4b81b38151adf3a14342afefadf7790656fb00d",
85
85
  "files": [
86
86
  "SKILL.md"
87
87
  ]
@@ -215,6 +215,8 @@ Quorum is human-only in the current public shape; its `audienceAndPricing.audien
215
215
 
216
216
  **Every quorum output `field()` must have a top-level array JSON schema.** The array is the collected-annotation dimension: one element per labeler, nominally `overlap` elements. Its `items` schema is one labeler's contribution.
217
217
 
218
+ Leave the outer array's length unbounded: it varies per item (fewer than `overlap` on a canceled item, up to `2 × overlap` under `llm_only` escalation). Validation rejects an outer `minItems` above 1 and an outer `maxItems` below `overlap` (below `2 × overlap` with `llm_only` QA). It also rejects `allOf`, `anyOf` or `oneOf` on the outer array; set length limits directly on it and put other constraints in `items`.
219
+
218
220
  Configure entities for one labeler's contribution, not for the outer array. A single label per person therefore uses `dynamic: false` and `jsonPath: '$.label'`, while the declared output field is `{ type: 'array', items: { type: 'string' } }`. `dynamic: true` means an array inside each labeler's contribution and therefore produces an array of arrays. Build the UI to submit one value at `$.label`, never `$.label[0]`; the platform assembles the outer array.
219
221
 
220
222
  When a quorum output entity is `optional: true`, its outer field's `items` schema must also accept `null`, for example `{ type: 'array', items: { type: ['string', 'null'] } }`. The platform reserves a null annotation slot when that labeler omits the value and rejects an optional entity backed by non-nullable items.
@@ -103,7 +103,9 @@ toloka training create "<training-name>" \
103
103
  --json
104
104
  ```
105
105
 
106
- Omit `--validation-dataset` when no separate validation selection exists so the provider uses its 10% holdout. For disjoint selections in a Dataset with top-level fields, add `--train-filter <field>=<value>` and `--validation-filter <field>=<value>`. For an existing Model Version source, replace `--base-model` with `--model-version <model-version-id>`.
106
+ Without `--validation-dataset`, the platform holds out 10% of training rows for evaluation. To select disjoint rows from top-level Dataset fields, use `--train-filter <field>=<value>` and `--validation-filter <field>=<value>`.
107
+
108
+ To continue from a Model Version, replace `--base-model` with `--model-version <model-version-id>`.
107
109
 
108
110
  Preserve requested hyperparameters. The current CLI uses `--lora-rank 8|16|32` (default 16), `--epochs 1..5` (default 3), `--learning-rate` within 0.00001–0.001 (default 0.00015), `--batch-size 8|16|32|64` (default 8), and `--max-sequence-length 64..16384` (default 12288), rather than `regime`. Use defaults when suitable; rank 8 can fit narrow tasks or small data, while 32 may help when 16 underfits and the data supports more capacity. Choose sequence length from actual examples within the supported limit. `--gist-tokens` is rejected for SFT. `training update <name-or-id>` takes the same flags except `--method`; omitted flags retain current values.
109
111
 
@@ -142,11 +144,19 @@ toloka training logs <training-run-id>
142
144
  toloka training metrics <training-run-id> --json
143
145
  ```
144
146
 
145
- Resume only after the user confirms a billing block is resolved. Cancel only on explicit request: before training starts it is free; during training it stops the GPU job and the run is charged for the GPU seconds used until then, with no Model Version.
147
+ Metrics can appear while the run is `running` and stop updating when training ends, before the run reaches `completed`. When `available: false`, check `unavailableReason`:
148
+
149
+ - `unresolved`: metrics are not available yet. Check again while the run is `running`.
150
+ - `not_configured`: this run will not report metrics. Stop polling for them.
151
+
152
+ Control and billing rules:
146
153
 
147
- A run can train longer than the estimate predicted. It stays `running`, the charge stays capped at the approved `maximumCharge`, and the Model Version publishes when training finishes; treat a slow run as still running, not as failed, and do not start a duplicate run for it. A run that ends `failed` with error code `provider_failed` or `provider_timeout` is a platform-side failure: it is charged nothing and the whole hold returns to the team balance, while its reported GPU seconds stay visible; a run the user cancels during training is charged for the GPU seconds used.
154
+ - Resume only after the user confirms a billing block is resolved.
155
+ - `payment_window_expired` is final: the run is `failed`, cannot resume, and was not charged, even though `billingStatus` remains `payment_required`. A replacement run needs funds and new cost approval.
156
+ - Cancel only on explicit request, before output checks begin. Before training starts, cancellation is free. During training, it stops the GPU job and charges for GPU seconds used, with no Model Version. A startup cancellation may remain `stopping` until the job stops; wait rather than retrying cancel.
157
+ - `provider_failed` and `provider_timeout` are platform failures: no charge, full hold returned. Reported GPU usage remains visible.
148
158
 
149
- A run can also wait for GPU capacity before training starts. In `training status --json` the run stays `running` while `progress.phase` is `queued` or `pending`; the wait can take hours when capacity is short, and the run starts training on its own. Treat it as still running.
159
+ Do not duplicate a slow run. Progress `queued` or `pending` means it is waiting for GPUs; training starts automatically. Training may also exceed the estimated duration. The charge stays capped at the approved `maximumCharge`; successful runs still publish a Model Version.
150
160
 
151
161
  For a completed run, verify the observed output and download only when requested:
152
162
 
@@ -112,7 +112,7 @@ toloka training create "<training-name>" \
112
112
  --json
113
113
  ```
114
114
 
115
- Omit `--validation-dataset` when no separate validation selection exists so the provider uses its 10% holdout. For disjoint selections in a Dataset with top-level fields, add `--train-filter <field>=<value>` and `--validation-filter <field>=<value>`.
115
+ Without `--validation-dataset`, the platform holds out 10% of training rows for evaluation. To select disjoint rows from top-level Dataset fields, use `--train-filter <field>=<value>` and `--validation-filter <field>=<value>`.
116
116
 
117
117
  Preserve requested hyperparameters. The current CLI uses `--gist-tokens` (default 32), `--epochs 1..5` (default 3), `--learning-rate` within 0.001–0.3 (default 0.03), `--batch-size 8|16|32|64` (default 8), and `--max-sequence-length 64..16384` (default 3072), rather than `regime`. Use defaults when suitable. `--gist-tokens` takes an absolute count `8|32|64` or a fraction of the prompt being compressed — `1/4`, `1/8`, `1/16`, `1/32`. An absolute count fixes the soft-prompt size: 8 favors compression for simple prompts, while 64 may help when 32 loses holdout accuracy. A fraction fixes the compression ratio instead — the run resolves it to `ceil(prompt tokens / N)` and clamps it to 8..256 — so prefer one for a long prompt or a prompt whose length changes between drafts, starting at `1/32`. `training get` reports the fraction you set, not the count it resolved to. Choose sequence length from actual examples within the supported limit. `--lora-rank` is rejected for gisting. `training update <name-or-id>` takes the same flags except `--method`; omitted flags retain current values.
118
118
 
@@ -151,11 +151,19 @@ toloka training logs <training-run-id>
151
151
  toloka training metrics <training-run-id> --json
152
152
  ```
153
153
 
154
- Resume only after the user confirms a billing block is resolved. Cancel only on explicit request: before training starts it is free; during training it stops the GPU job and the run is charged for the GPU seconds used until then, with no Model Version.
154
+ Metrics can appear while the run is `running` and stop updating when training ends, before the run reaches `completed`. When `available: false`, check `unavailableReason`:
155
155
 
156
- A run can train longer than the estimate predicted. It stays `running`, the charge stays capped at the approved `maximumCharge`, and the Model Version publishes when training finishes; treat a slow run as still running, not as failed, and do not start a duplicate run for it. A run that ends `failed` with error code `provider_failed` or `provider_timeout` is a platform-side failure: it is charged nothing and the whole hold returns to the team balance, while its reported GPU seconds stay visible; a run the user cancels during training is charged for the GPU seconds used.
156
+ - `unresolved`: metrics are not available yet. Check again while the run is `running`.
157
+ - `not_configured`: this run will not report metrics. Stop polling for them.
157
158
 
158
- A run can also wait for GPU capacity before training starts. In `training status --json` the run stays `running` while `progress.phase` is `queued` or `pending`; the wait can take hours when capacity is short, and the run starts training on its own. Treat it as still running.
159
+ Control and billing rules:
160
+
161
+ - Resume only after the user confirms a billing block is resolved.
162
+ - `payment_window_expired` is final: the run is `failed`, cannot resume, and was not charged, even though `billingStatus` remains `payment_required`. A replacement run needs funds and new cost approval.
163
+ - Cancel only on explicit request, before output checks begin. Before training starts, cancellation is free. During training, it stops the GPU job and charges for GPU seconds used, with no Model Version. A startup cancellation may remain `stopping` until the job stops; wait rather than retrying cancel.
164
+ - `provider_failed` and `provider_timeout` are platform failures: no charge, full hold returned. Reported GPU usage remains visible.
165
+
166
+ Do not duplicate a slow run. Progress `queued` or `pending` means it is waiting for GPUs; training starts automatically. Training may also exceed the estimated duration. The charge stays capped at the approved `maximumCharge`; successful runs still publish a Model Version.
159
167
 
160
168
  For a completed run, verify the observed output and download only when requested:
161
169
 
package/src/cli/auth.ts CHANGED
@@ -343,10 +343,20 @@ const loginInBrowser = async (
343
343
  };
344
344
  };
345
345
 
346
+ const readValidStoredCredentials = async (environment: CliEnvironment): Promise<StoredCredentials | undefined> => {
347
+ for (const path of storedCredentialsPaths(environment)) {
348
+ const inspected = await inspectCredentialsFile(path);
349
+ if (inspected === "missing") continue;
350
+ return typeof inspected === "object" ? inspected.credentials : undefined;
351
+ }
352
+ return undefined;
353
+ };
354
+
346
355
  export async function login(options: LoginOptions = {}): Promise<LoginResult> {
347
356
  const environment = options.environment ?? process.env;
348
357
  const write = options.write ?? (() => undefined);
349
- const baseUrl = normalizeBaseUrl(resolveBaseUrl(options, environment));
358
+ const stored = await readValidStoredCredentials(environment);
359
+ const baseUrl = normalizeBaseUrl(resolveBaseUrl(options, environment, stored));
350
360
  const environmentKey = options.browser === undefined ? environment.TOLOKA_API_KEY : undefined;
351
361
  if (options.apiKey !== undefined || environmentKey !== undefined) {
352
362
  return loginWithApiKey(options, environment, baseUrl, write);
@@ -403,13 +413,7 @@ export async function logout(
403
413
  environment: CliEnvironment = process.env,
404
414
  options: LogoutOptions = {},
405
415
  ): Promise<LogoutResult> {
406
- let stored: StoredCredentials | undefined;
407
- for (const path of storedCredentialsPaths(environment)) {
408
- const inspected = await inspectCredentialsFile(path);
409
- if (inspected === "missing") continue;
410
- stored = typeof inspected === "object" ? inspected.credentials : undefined;
411
- break;
412
- }
416
+ const stored = await readValidStoredCredentials(environment);
413
417
  const baseUrl = normalizeBaseUrl(resolveBaseUrl(options, environment, stored));
414
418
  const removed = await clearStoredCredentials(environment);
415
419
  const browsers = await endBrowserLogins(environment, options.fetch);
@@ -610,6 +610,7 @@ export const createTrainingRun = async (
610
610
  const prepared = await prepareTrainingCostEstimate(client, {
611
611
  projectId: input.projectId,
612
612
  nameOrId: input.nameOrId,
613
+ idempotencyKey: input.idempotencyKey,
613
614
  });
614
615
  assertCli(prepared.estimate.status === "ready", formatCostEstimate(prepared.estimate), {
615
616
  hint: {