@toloka-platform/sdk 0.5.2 → 0.7.0

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
- 4144ed5bb1a0a9b6f7b983e854cc0094315f954e25f0a31097f6394bc7adc7dd toloka.js.jsc
1
+ 30d0eef954604da0ab6e662126d751d0eb677591165ef5b31e14361c56e79382 toloka.js.jsc
@@ -1 +1 @@
1
- babd9144be52b672bdbba134f9820f13e96c51081f7600408354e564aeb8ef13 toloka.js
1
+ 2d31d0710cec35995c270ff736eb345527ef21fd19f0344e0f886929b6182826 toloka.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toloka-platform/sdk",
3
- "version": "0.5.2",
3
+ "version": "0.7.0",
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": "ae2c20f000f63863115fd153a0e15dc599dd85ed"
80
+ "commit": "34be4b356a94120e00a825e949921d584ecdcbcf"
81
81
  }
82
82
  }
@@ -11,8 +11,8 @@
11
11
  "testing",
12
12
  "checks"
13
13
  ],
14
- "version": "0.5.2",
15
- "digest": "0c36f68ae116fe72362d43c9a2b4bc74685614c41f8bccf1fb053b2d13a1ea94",
14
+ "version": "0.7.0",
15
+ "digest": "c17a1c4f9b3b974ae07859bc3ac7669d98d47d9984e174712f550ef7c3204d63",
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.5.2",
32
+ "version": "0.7.0",
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.5.2",
49
+ "version": "0.7.0",
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.5.2",
67
- "digest": "f9c34569fc344f365c79c86819adffc86c78a2ce74e17ba10755ddefaf71790f",
66
+ "version": "0.7.0",
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.5.2",
84
- "digest": "902aee47c952e105a6340ee56bf22e79513e2d45d19a7ffbf58990f277387e34",
83
+ "version": "0.7.0",
84
+ "digest": "4501e480901fc32c26de0314b4b81b38151adf3a14342afefadf7790656fb00d",
85
85
  "files": [
86
86
  "SKILL.md"
87
87
  ]
@@ -76,7 +76,7 @@ Use `node_modules/@toloka-platform/sdk/examples/face-image-collection/` as a con
76
76
 
77
77
  Distinguish server requirements from optional design choices. The following constraints and defaults are not all checked by `definePipeline`:
78
78
 
79
- - **Do not pair `projectType: 'general'` with `verifiedExperts: false`.** The server answers `General projects require an ID-verified audience`. Specializations also require a verified audience.
79
+ - **Specializations require a verified audience.** Pair `audience.specializations` with `verifiedExperts: true`. Any project type may use the broad unverified crowd; the default is verified, so set `verifiedExperts: false` only when the task asks for it.
80
80
  - **Training is part of the node, not extra.** A quorum node requires `onboarding`, and while it is enabled the platform wants at least three steps and at least one quiz block. Preserve an explicit `enabled: false` that a user or `toloka import` put there; never switch Training on to satisfy your own sense of completeness.
81
81
  - **Optional settings should serve the task.** Exams, non-default QA, audience reuse, and smart search can be useful when the requirements call for them. Omit blocks that add no value rather than copying placeholders; an empty disabled block is still authored state. Preserve imported choices unless changing them is part of the task, and explain additions that affect cost or expert eligibility.
82
82
  - **Run scope belongs to the platform.** `itemFilter` and `itemLimit` on the root node are set from the platform, and apply preserves whatever is live unless source declares its own value. Do not add an item limit to source to "restore" one you saw in the UI.
@@ -117,7 +117,7 @@ Use `generation` for a single human-in-the-loop task type:
117
117
 
118
118
  Use `about.projectType: 'general'` when experts act on existing items: annotation, classification, judgment, ranking, rating, comparison, or rewriting.
119
119
 
120
- Use `about.projectType: 'data_collection'` when experts produce new original content instead of labeling an existing item. Build the UI with the corresponding upload or recording component. Prefer the larger unverified crowd for this work by setting `audienceAndPricing.verifiedExperts: false` unless the task specifically requires verified expertise. Do not use an unverified audience for a `general` project.
120
+ Use `about.projectType: 'data_collection'` when experts produce new original content instead of labeling an existing item. Build the UI with the corresponding upload or recording component.
121
121
 
122
122
  ### Configure it
123
123
 
@@ -164,7 +164,7 @@ Keep `instruction` actionable and in English. Include the workflow, concepts, qu
164
164
 
165
165
  #### Audience and pricing
166
166
 
167
- For humans, set `audienceType: 'human'`, `verifiedExperts`, all three audience filters, `pricePerTask`, and `timeForTask`. The public shapes differ by filter: languages use `{ type: 'and' | 'or', values: [{ value: 'English' }] }`; specializations use `{ type: 'and' | 'or', values: [{ value, qualificationId }] }`; countries use ISO 3166-1 alpha-2 codes, for example `{ type: 'or', values: ['US'] }`. Verify every country value matches `/^[A-Z]{2}$/`; apply currently accepts arbitrary strings that can match no experts. Derive languages and expertise from the task and its inputs, leaving specialization and country filters unrestricted unless needed. English is a reasonable starting language for an English-language task, not a universal audience default. Ask when an unresolved audience requirement changes who can do the work. Do not put specializations on an unverified audience. A specialization's `qualificationId` is platform identity: preserve an imported value, and discover new ones with `toloka audience specialization list`, copying `ID` into `qualificationId` and `NAME` into `value`; never invent one.
167
+ For humans, set `audienceType: 'human'`, `verifiedExperts`, all three audience filters, `pricePerTask`, and `timeForTask`. Set `verifiedExperts: true` unless the task explicitly asks for the broad unverified crowd. The public shapes differ by filter: languages use `{ type: 'and' | 'or', values: [{ value: 'English' }] }`; specializations use `{ type: 'and' | 'or', values: [{ value, qualificationId }] }`; countries use ISO 3166-1 alpha-2 codes, for example `{ type: 'or', values: ['US'] }`. Verify every country value matches `/^[A-Z]{2}$/`; apply currently accepts arbitrary strings that can match no experts. Derive languages and expertise from the task and its inputs, leaving specialization and country filters unrestricted unless needed. English is a reasonable starting language for an English-language task, not a universal audience default. Ask when an unresolved audience requirement changes who can do the work. Do not put specializations on an unverified audience. A specialization's `qualificationId` is platform identity: preserve an imported value, and discover new ones with `toloka audience specialization list`, copying `ID` into `qualificationId` and `NAME` into `value`; never invent one.
168
168
 
169
169
  `$0.20` and 120 seconds are a starting point for a short task, not a universal rate. Estimate effort from the work and required expertise, respect explicit rates, and explain meaningful adjustments in the cost forecast. The per-expert cap is normally off. For collection tasks, choose a cap based on contributor diversity and repetition requirements; 1 fits one-response-per-expert collection. Avoid copying an arbitrary cap into a task that does not need one.
170
170
 
@@ -187,7 +187,8 @@ Use `reuseAudienceWithNodeId` only with real imported `{ pipelineId, nodeId }` v
187
187
  - Do not add fields, explanations, comments, or labor the task does not require.
188
188
  - Do not choose synthetic generation merely because a model could do the task; require an explicit request.
189
189
  - Do not treat the constructor's generated placeholder Training or blank UI as production-ready configuration.
190
- - Do not pair `projectType: 'general'` with `verifiedExperts: false`. General projects require an ID-verified audience, and the server rejects the graph with `General projects require an ID-verified audience`. `data_collection` supports both modes but requires a hardware upload or recording component supported by the current UI catalog. An annotation task with an unverified audience therefore cannot be expressed: `general` demands verified experts and `data_collection` demands an upload control the task has no use for. When a request asks for one, say so and let the requester choose, rather than quietly flipping a setting.
190
+ - Do not pair `audience.specializations` with `verifiedExperts: false`. Specializations are qualification-backed, and only verified experts hold them.
191
+ - Do not flip an explicitly requested `verifiedExperts: false` to `true`. Every project type accepts either audience mode.
191
192
  - Do not omit `ui.constants`. It is required alongside `code`, `data`, `preprocess`, and `postprocess`; `'{}'` is the right value when there is nothing to pass. Omitting it fails validation with `must have required property 'constants'`, usually reported together with a misleading `type must be equal to constant` from the failed node discrimination.
192
193
  - Do not omit `maxCostPerAttempt` from a synthetic `audienceAndPricing`. Omitting it fails validation with `must have required property 'maxCostPerAttempt'`, reported together with a misleading `type must be equal to constant` and the human branch's `must have required property 'verifiedExperts'` from the failed `oneOf` discrimination.
193
194
  - Do not ship a generation node without Training. `onboarding` is mandatory: at least three `steps`, of which at least one carries a `quiz` block. The server rejects fewer with `Onboarding must have at least 3 steps` and `Onboarding must include at least one quiz block`.
@@ -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: {