@toloka-platform/sdk 0.2.0-preview.4 → 0.2.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.
Files changed (46) hide show
  1. package/README.md +5 -6
  2. package/dist/cli/toloka.js +156 -137
  3. package/dist/cli/toloka.js.jsc +0 -0
  4. package/dist/cli/toloka.js.jsc.sha256 +1 -1
  5. package/dist/cli/toloka.js.sha256 +1 -1
  6. package/docs/authoring.md +2 -0
  7. package/docs/cli.md +16 -6
  8. package/docs/getting-started.md +4 -2
  9. package/docs/limitations.md +2 -2
  10. package/openapi/gen/api.ts +30 -0
  11. package/openapi/gen/models/gistingTrainingConfigurationGistTokens.ts +1 -1
  12. package/openapi/gen/models/gistingTrainingConfigurationInputGistTokens.ts +1 -1
  13. package/openapi/gen/models/index.ts +3 -0
  14. package/openapi/gen/models/listAudienceSpecializations200.ts +7 -0
  15. package/openapi/gen/models/listAudienceSpecializationsParams.ts +5 -0
  16. package/openapi/gen/models/specialization.ts +6 -0
  17. package/openapi/gen/models/trainingCostEstimateOneOfTwoseven.ts +0 -2
  18. package/openapi/gen/models/trainingRunQuote.ts +0 -2
  19. package/package.json +2 -2
  20. package/skills/catalog.json +10 -10
  21. package/skills/toloka-build/SKILL.md +1 -1
  22. package/skills/toloka-build/references/node-semantics.md +2 -2
  23. package/skills/toloka-build/references/workflow-and-cli.md +8 -5
  24. package/skills/toloka-fine-tuning/SKILL.md +3 -1
  25. package/skills/toloka-get-started/SKILL.md +3 -2
  26. package/skills/toloka-gisting/SKILL.md +5 -3
  27. package/skills/toloka-report-issue/references/report-template.md +1 -1
  28. package/src/checks/task-ui-typecheck.ts +4 -1
  29. package/src/cli/analytics.ts +1 -0
  30. package/src/cli/audience.ts +31 -0
  31. package/src/cli/auto-update.ts +363 -24
  32. package/src/cli/check.ts +51 -52
  33. package/src/cli/cli-entry.ts +31 -0
  34. package/src/cli/commands/audience.ts +22 -0
  35. package/src/cli/commands/training.ts +10 -2
  36. package/src/cli/context.ts +7 -2
  37. package/src/cli/init.ts +7 -2
  38. package/src/cli/models.ts +1 -21
  39. package/src/cli/native-runtime.ts +7 -0
  40. package/src/cli/program.ts +3 -1
  41. package/src/cli/skill.ts +34 -26
  42. package/src/cli/table.ts +21 -0
  43. package/src/cli/trainings.ts +1 -22
  44. package/src/cli/version.ts +12 -1
  45. package/src/client.ts +17 -0
  46. package/src/index.ts +1 -0
Binary file
@@ -1 +1 @@
1
- ee914e999937f98c40a657d10640ea64acda93b2e50f4a9306e25453c8897248 toloka.js.jsc
1
+ 5c6e6ba38b31803da60d3f8371a159ce99d5e156595e002cd7a4f6e6c9432cf8 toloka.js.jsc
@@ -1 +1 @@
1
- fabf11ce7545f788c03870778c18deda006d89c95c839ae8c1592f4eaa287366 toloka.js
1
+ 88ba4c829ee5f68917b216cfdaefcbf44528cb059013afd242f499d15caf506d toloka.js
package/docs/authoring.md CHANGED
@@ -152,6 +152,8 @@ export const annotateFaces = generation("annotate_faces", {
152
152
  });
153
153
  ```
154
154
 
155
+ To require a specialization, add `{ value, qualificationId }` entries to `audience.specializations.values`. Both come from the platform catalog — `toloka audience specialization list` — where `NAME` is the `value`, `ID` is the `qualificationId`, and `EXPERTS` tells you how large the pool is. Specializations require `verifiedExperts: true`.
156
+
155
157
  Test the interface locally before applying it. The SDK's Vitest fixture renders this exact `ui` block in Chromium, interacts with Fields by `path`, runs postprocess, validates output entities, and saves screenshots. See [Test pipelines locally](./testing.md).
156
158
 
157
159
  ### quorum
package/docs/cli.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  The `toloka` CLI reads TypeScript source as the desired state, compares it with the live platform state, and reconciles the two.
4
4
 
5
- This CLI is Beta software. Commands, flags, and output can change before general availability.
5
+ `toloka` `0.2.0` is the current stable CLI on the `latest` channel. Because it ships as part of the `0.x` SDK, commands, flags, and output can change between minor releases.
6
6
 
7
7
  `toloka` requires Bun 1.4.0 or newer. The published package ships CLI bytecode built with Bun 1.4.0; another Bun version runs the same bundled JavaScript without that cache and starts slower. The launcher falls back to TypeScript source in a development checkout when the bytecode is absent.
8
8
 
@@ -30,7 +30,7 @@ Credentials and the platform base URL resolve from the same precedence order, hi
30
30
  | 3 | `projectId` in `toloka.json` |
31
31
  | 4 (lowest) | `current` alias in the credentials file |
32
32
 
33
- Earlier releases named these variables `POTATO_API_KEY`, `POTATO_BASE_URL`, and `POTATO_PROJECT_ID`. The CLI still reads each legacy name when its `TOLOKA_*` counterpart is unset, prefers the `TOLOKA_*` value when both are set, and prints `POTATO_API_KEY is deprecated and will stop being read; set TOLOKA_API_KEY instead.` (and the same line for the other two) on stderr once per command. The legacy names stop being read in the first stable `0.2.0` release; rename them now to silence the warning.
33
+ Earlier releases named these variables `POTATO_API_KEY`, `POTATO_BASE_URL`, and `POTATO_PROJECT_ID`. The CLI still reads each legacy name when its `TOLOKA_*` counterpart is unset, prefers the `TOLOKA_*` value when both are set, and prints `POTATO_API_KEY is deprecated and will stop being read; set TOLOKA_API_KEY instead.` (and the same line for the other two) on stderr once per command. The aliases remain supported for compatibility; rename them to silence the warning and use the current names in new automation.
34
34
 
35
35
  `toloka login` verifies the key against the platform before saving anything. It writes `$XDG_CONFIG_HOME/toloka/credentials.json`, which defaults to `~/.config/toloka/credentials.json`, with file mode `0600` and a parent directory with mode `0700`. The file may also store local project aliases. The legacy `~/.toloka/credentials.json` is still read when the new path has no file. `toloka logout` deletes the stored file but does not revoke the key.
36
36
 
@@ -108,6 +108,16 @@ toloka delivery-order list
108
108
 
109
109
  Prints `ID`, `NAME`, `STATUS`, and `CLIENT` columns. Empty output is `No delivery orders visible.`
110
110
 
111
+ ## audience
112
+
113
+ Inspect the global, read-only expert audience catalog: the values a node's `audienceAndPricing.audience` filter can use.
114
+
115
+ ```sh
116
+ toloka audience specialization list [--json]
117
+ ```
118
+
119
+ Lists every expert specialization (platform qualification) with `ID`, `NAME`, and `EXPERTS` columns, sorted by name. Copy `ID` into `qualificationId` and `NAME` into `value` of `audience.specializations.values[]`; never invent a `qualificationId`. `EXPERTS` is the number of ID-verified experts currently eligible for tasks who hold the specialization; it can be `0` while the id is still valid. Pass `--json` for the full array. Empty output is `No specializations available.`
120
+
111
121
  ## login
112
122
 
113
123
  Stores an API key for this machine after verifying it.
@@ -294,8 +304,8 @@ Create a reusable Training draft, price it, and run it.
294
304
  ```sh
295
305
  toloka training list [--json]
296
306
  toloka training get <name-or-id> [--json]
297
- toloka training create <name> [--method sft|gisting] (--base-model <id> | --model-version <id>) --dataset <id> [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
298
- toloka training update <name-or-id> [--base-model <id> | --model-version <id>] [--dataset <id>] [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
307
+ toloka training create <name> [--method sft|gisting] (--base-model <id> | --model-version <id>) --dataset <id> [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64|1/4|1/8|1/16|1/32] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
308
+ toloka training update <name-or-id> [--base-model <id> | --model-version <id>] [--dataset <id>] [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64|1/4|1/8|1/16|1/32] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
299
309
  toloka training cost <name-or-id> [--idempotency-key <key>] [--json]
300
310
  toloka training run <name-or-id> [--estimate-file <path>] [--version-name <name>] [--idempotency-key <key>] [--json]
301
311
  toloka training runs <name-or-id> [--json]
@@ -306,7 +316,7 @@ toloka training logs <training-run-id>
306
316
  toloka training metrics <training-run-id> [--key <metric>] [--resolution <n>] [--json]
307
317
  ```
308
318
 
309
- Hyperparameters are optional flags on `training create` and `training update`: `--epochs 1..5` (default 3), `--learning-rate` (SFT 0.00001–0.001, default 0.00015; gisting 0.001–0.3, default 0.03), `--batch-size 8|16|32|64` (default 8; sequences per optimizer step across all GPUs) and `--max-sequence-length 64..16384` (default 12288 for SFT, 3072 for gisting) apply to both methods; `--lora-rank 8|16|32` (default 16) is SFT-only and `--gist-tokens 8|32|64` (default 32) is gisting-only — passing one to the other method fails before any request. `--regime` and `--eval-steps` no longer exist. `training update` has no `--method` flag: the method stays as created, and every flag you omit keeps its current value. `training cost` is blocked when the longest example exceeds `--max-sequence-length` or when the training selection leaves fewer rows than `--batch-size` after the 10% holdout. `training get` prints the resolved recipe, so omitted flags are visible as their defaults.
319
+ Hyperparameters are optional flags on `training create` and `training update`: `--epochs 1..5` (default 3), `--learning-rate` (SFT 0.00001–0.001, default 0.00015; gisting 0.001–0.3, default 0.03), `--batch-size 8|16|32|64` (default 8; sequences per optimizer step across all GPUs) and `--max-sequence-length 64..16384` (default 12288 for SFT, 3072 for gisting) apply to both methods; `--lora-rank 8|16|32` (default 16) is SFT-only and `--gist-tokens` (default 32) is gisting-only — passing one to the other method fails before any request. `--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`), which the run resolves to `ceil(prompt tokens / N)` clamped to 8..256. `--regime` and `--eval-steps` no longer exist. `training update` has no `--method` flag: the method stays as created, and every flag you omit keeps its current value. `training cost` is blocked when the longest example exceeds `--max-sequence-length` or when the training selection leaves fewer rows than `--batch-size` after the 10% holdout. `training get` prints the resolved recipe, so omitted flags are visible as their defaults.
310
320
 
311
321
  ## dataset
312
322
 
@@ -362,7 +372,7 @@ toloka skill install <skillId> [--force]
362
372
 
363
373
  After an SDK upgrade `list` reports installed skills whose catalog digest changed as `stale` until they are refreshed with `install --force`. Local edits to an installed skill also make it `stale`; `list` and `search` never modify local files.
364
374
 
365
- The catalog is bound to the installed package version, so a skill that a newer release ships is simply absent from an older CLI. `install` then exits 1 with `Skill "<skillId>" is not in the catalog bundled with @toloka-platform/sdk <version>. Run toloka skill list to see the available skills; a newer release may ship it (bun add --global @toloka-platform/sdk@<channel>).` and creates nothing. `<channel>` is the channel of the installed version (`preview` for a `-preview.N` version, otherwise `latest`); reinstall from it and retry.
375
+ The catalog is bound to the installed package version, so a skill that a newer release ships is simply absent from an older CLI. `install` then exits 1, names the missing skill and installed package version, and creates nothing. Run `toloka skill list` to see the available skills. To get the current supported catalog, update with `bun add --global @toloka-platform/sdk@latest` and retry.
366
376
 
367
377
  ## Exit codes
368
378
 
@@ -4,7 +4,7 @@ Install the SDK, sign in, and get a pipeline project reconciling from source in
4
4
 
5
5
  ## Install
6
6
 
7
- Install the bytecode-cached CLI globally and declare the Beta SDK in the project:
7
+ Install the bytecode-cached CLI globally and declare the stable SDK in the project:
8
8
 
9
9
  ```sh
10
10
  curl -fsSL https://platform.toloka.ai/cli/install.sh | sh
@@ -13,6 +13,8 @@ bun add @toloka-platform/sdk@latest
13
13
 
14
14
  The installer requires Bun 1.4.0 or newer, installs `@toloka-platform/sdk` globally, and exposes `toloka` through Bun's global binary directory. The published CLI includes bytecode built with Bun 1.4.0; another Bun version runs the same bundled JavaScript without that cache and starts slower. The project install makes SDK imports resolvable.
15
15
 
16
+ `latest` currently installs stable `0.2.0`, including Training commands and the bundled agent runbooks and skills. Use `bun add @toloka-platform/sdk@0.2.0` when you need an exact, reproducible project dependency.
17
+
16
18
  ## Sign in
17
19
 
18
20
  ```sh
@@ -140,4 +142,4 @@ Exit code `0` means the run reached a successful terminal state, `1` a failed on
140
142
  - [Nodes](./nodes.md) — which node to reach for, and the pricing floors you must clear
141
143
  - [CLI](./cli.md) — every command and flag
142
144
  - [Troubleshooting](./troubleshooting.md) — the failures you will hit
143
- - [Limitations](./limitations.md) — Beta status and what this SDK does not do yet
145
+ - [Limitations](./limitations.md) — current constraints and `0.x` compatibility expectations
@@ -1,8 +1,8 @@
1
1
  # Limitations
2
2
 
3
- What this Beta SDK does not do yet, stated plainly so you can decide what to depend on.
3
+ Current constraints of the stable SDK, stated plainly so you can decide what to depend on.
4
4
 
5
- `@toloka-platform/sdk` is `0.2.0-preview.3`. This is a Beta: the authoring API, the CLI surface, and the generated source layout can change before general availability. Pin an exact version. Do not depend on this in production yet.
5
+ `@toloka-platform/sdk` `0.2.0` is the current stable release on `latest`. Because it is a `0.x` release, the authoring API, CLI surface, and generated source layout can change between minor versions. Use `latest` for the current supported release, or pin `@toloka-platform/sdk@0.2.0` for reproducible installs.
6
6
 
7
7
  ## Local checks do not certify deployability
8
8
 
@@ -32,6 +32,8 @@ import type {
32
32
  GetTrainingRunLogsParams,
33
33
  GetTrainingRunMetricHistoryParams,
34
34
  ImportPipelineBody,
35
+ ListAudienceSpecializations200,
36
+ ListAudienceSpecializationsParams,
35
37
  ListBaseModels200,
36
38
  ListDatasetFields200,
37
39
  ListDatasetFieldsParams,
@@ -686,6 +688,34 @@ export const cancelTrainingRun = async (trainingRunId: TrainingRunId, options?:
686
688
 
687
689
 
688
690
 
691
+ export const getListAudienceSpecializationsUrl = (params?: ListAudienceSpecializationsParams,) => {
692
+ const normalizedParams = new URLSearchParams();
693
+
694
+ Object.entries(params || {}).forEach(([key, value]) => {
695
+
696
+ if (value !== undefined) {
697
+ normalizedParams.append(key, value === null ? 'null' : value.toString())
698
+ }
699
+ });
700
+
701
+ const stringifiedParams = normalizedParams.toString();
702
+
703
+ return stringifiedParams.length > 0 ? `/api/v2-beta/audience/specializations?${stringifiedParams}` : `/api/v2-beta/audience/specializations`
704
+ }
705
+
706
+ export const listAudienceSpecializations = async (params?: ListAudienceSpecializationsParams, options?: RequestInit): Promise<ListAudienceSpecializations200> => {
707
+
708
+ return potatoFetch<ListAudienceSpecializations200>(getListAudienceSpecializationsUrl(params),
709
+ {
710
+ ...options,
711
+ method: 'GET'
712
+
713
+
714
+ }
715
+ );}
716
+
717
+
718
+
689
719
  export const getGetCurrentUserUrl = () => {
690
720
 
691
721
 
@@ -1,2 +1,2 @@
1
1
 
2
- export type GistingTrainingConfigurationGistTokens = 8 | 32 | 64;
2
+ export type GistingTrainingConfigurationGistTokens = 8 | 32 | 64 | '1/4' | '1/8' | '1/16' | '1/32';
@@ -1,2 +1,2 @@
1
1
 
2
- export type GistingTrainingConfigurationInputGistTokens = 8 | 32 | 64;
2
+ export type GistingTrainingConfigurationInputGistTokens = 8 | 32 | 64 | '1/4' | '1/8' | '1/16' | '1/32';
@@ -280,6 +280,8 @@ export * from './jsonSchema';
280
280
  export * from './jsonSchemaAdditionalProperties';
281
281
  export * from './jsonSchemaType';
282
282
  export * from './jsonSchemaTypeAnyOfItem';
283
+ export * from './listAudienceSpecializations200';
284
+ export * from './listAudienceSpecializationsParams';
283
285
  export * from './listBaseModels200';
284
286
  export * from './listDatasetFields200';
285
287
  export * from './listDatasetFieldsParams';
@@ -829,6 +831,7 @@ export * from './sftTrainingConfigurationInput';
829
831
  export * from './sftTrainingConfigurationInputBatchSize';
830
832
  export * from './sftTrainingConfigurationInputLoraRank';
831
833
  export * from './sftTrainingConfigurationLoraRank';
834
+ export * from './specialization';
832
835
  export * from './training';
833
836
  export * from './trainingArchivedAt';
834
837
  export * from './trainingConfiguration';
@@ -0,0 +1,7 @@
1
+ import type { Specialization } from './specialization';
2
+ import type { Pagination } from './pagination';
3
+
4
+ export type ListAudienceSpecializations200 = {
5
+ specializations: Specialization[];
6
+ pagination: Pagination;
7
+ };
@@ -0,0 +1,5 @@
1
+
2
+ export type ListAudienceSpecializationsParams = {
3
+ limit?: number;
4
+ offset?: number;
5
+ };
@@ -0,0 +1,6 @@
1
+
2
+ export interface Specialization {
3
+ id: string;
4
+ name: string;
5
+ expertsCount: number;
6
+ }
@@ -15,8 +15,6 @@ export type TrainingCostEstimateOneOfTwoseven = {
15
15
  status: 'ready';
16
16
  issues: TrainingCostEstimateOneOfTwosevenIssuesItem[];
17
17
  budget: TrainingCostEstimateOneOfTwosevenBudget;
18
- basePricePerGpuHour: string;
19
- marginMultiplier: string;
20
18
  maximumCharge: string;
21
19
  currency: 'USD';
22
20
  fingerprint: string;
@@ -10,8 +10,6 @@ export type TrainingRunQuote = {
10
10
  pricingVersion: string;
11
11
  calculatedAt: string;
12
12
  budget: TrainingRunQuoteBudget;
13
- basePricePerGpuHour: string;
14
- marginMultiplier: string;
15
13
  maximumCharge: string;
16
14
  currency: 'USD';
17
15
  };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@toloka-platform/sdk",
3
- "version": "0.2.0-preview.4",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
- "description": "Beta. Build, inspect, and operate Toloka pipeline projects as TypeScript source. The public API may change.",
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",
7
7
  "bin": {
8
8
  "toloka": "bin/toloka.js"
@@ -11,8 +11,8 @@
11
11
  "testing",
12
12
  "checks"
13
13
  ],
14
- "version": "0.2.0-preview.4",
15
- "digest": "2d27360563da6ff5ef41d264982d89232087cf7c76393022c83a66c5301752b3",
14
+ "version": "0.2.1",
15
+ "digest": "b7ffd9ccebdbb7cae9cf672cd3e43afa2c353398b8ea89a2558e8b7277b83fb7",
16
16
  "files": [
17
17
  "SKILL.md",
18
18
  "references/node-semantics.md",
@@ -29,8 +29,8 @@
29
29
  "bug",
30
30
  "report"
31
31
  ],
32
- "version": "0.2.0-preview.4",
33
- "digest": "76229bae596f8a1722ce7fc55bea3dd66698df5b61baa31f6cb98ca2b5fa03e8",
32
+ "version": "0.2.1",
33
+ "digest": "56a0c283649052c85ba882f05d4a996bd98bf1bc011bc7a70af234b3664057d6",
34
34
  "files": [
35
35
  "SKILL.md",
36
36
  "references/report-template.md"
@@ -46,8 +46,8 @@
46
46
  "getting-started",
47
47
  "agent"
48
48
  ],
49
- "version": "0.2.0-preview.4",
50
- "digest": "f86ba45aba0bf2b06bc02b65c6f3dbb7b9b4cb28630191bafa62b6e627448138",
49
+ "version": "0.2.1",
50
+ "digest": "61a3cf60f0b7d00e48c9663ed6e0e3d77fd3923e528cee52e16ef6e2ccebae69",
51
51
  "files": [
52
52
  "SKILL.md"
53
53
  ]
@@ -63,8 +63,8 @@
63
63
  "sft",
64
64
  "models"
65
65
  ],
66
- "version": "0.2.0-preview.4",
67
- "digest": "81c43af9e78e1df322085dd2ec923e85a7be0d084c689906aa5db6cdbd03c9e3",
66
+ "version": "0.2.1",
67
+ "digest": "75b7909bfaf8fdc13a91515efdcdbdcad31fd3355fa3401f22ee66e24258098c",
68
68
  "files": [
69
69
  "SKILL.md"
70
70
  ]
@@ -80,8 +80,8 @@
80
80
  "prompt",
81
81
  "models"
82
82
  ],
83
- "version": "0.2.0-preview.4",
84
- "digest": "ee30f006d8f7995a825db5e7c74732e35517d88b43a4f6671d6439f1c333c815",
83
+ "version": "0.2.1",
84
+ "digest": "8bd6fee5baa84e6f94871eebf34e916bf3f5deb202c60fb9e063ebbc68ddb5b3",
85
85
  "files": [
86
86
  "SKILL.md"
87
87
  ]
@@ -5,7 +5,7 @@ description: Build, test, inspect, or change Toloka platform pipeline projects a
5
5
 
6
6
  # Build Toloka pipelines as code
7
7
 
8
- This SDK is Beta software. The authoring API, the CLI, and generated source can change before general availability. Do not invent helpers or flags that are not in the installed package.
8
+ This SDK follows `0.x` versioning, so the authoring API, the CLI, and generated source can change between releases. Use the API and commands exposed by the installed package; do not invent helpers or flags.
9
9
 
10
10
  Help the user get a working pipeline that fits their task: understand the data and desired output, choose a suitable design, verify it, and apply or run it when requested. Work in the project source tree; TypeScript is the pipeline's desired state, not a transcription of direct platform API calls.
11
11
 
@@ -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 do not invent one when the SDK cannot discover it.
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.
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
 
@@ -281,7 +281,7 @@ Ordering is semantic: `conditions[0]` routes to `matched(0)`, the first true con
281
281
 
282
282
  When the requirement depends on one of these capabilities, state the gap instead of inventing source syntax:
283
283
 
284
- - Audience discovery and validation helpers have no SDK or CLI path: valid-language/country/specialization suggestions, audience-size statistics, and recommended-rate calculation.
284
+ - Audience discovery beyond specializations has no SDK or CLI path: valid-language/country suggestions, audience-size statistics for a composed filter, and recommended-rate calculation. Specializations and their expert counts come from `toloka audience specialization list`.
285
285
  - Audience-reuse candidate discovery has no SDK or CLI path. Source can store a known cross-pipeline pointer, but cannot search candidates.
286
286
  - Smart Search rendering, source-fingerprint computation, and stale-profile diagnosis have no SDK or CLI path. Source can carry the public profile; it cannot generate the server-owned fingerprint or preview rendered sourcing documents.
287
287
  - The `@toloka-platform/sdk/testing` entry point provides typed `test.code`, `test.ui`, and `test.pipeline` wrappers. `toloka check` runs their evidence with project TypeScript and automatic Task UI typechecking. Missing Remote Node Checks remain separate from this local gate.
@@ -31,7 +31,7 @@ For a first-time guided session, consult `https://platform.toloka.ai/agents/data
31
31
  Install the SDK before invoking project commands:
32
32
 
33
33
  ```sh
34
- bun add --dev @toloka-platform/sdk
34
+ bun add --dev @toloka-platform/sdk@latest
35
35
  ```
36
36
 
37
37
  Select or create the intended platform project before `toloka init` when the checkout should be bound immediately; follow the adoption or scratch recipe below. Running `init` without explicit or checkout-local project identity installs only the agent entry points and never adopts the machine registry's current project.
@@ -105,6 +105,7 @@ toloka project remove <alias>
105
105
  toloka project create [alias] [--name <name>] [--team-id <id>] [--delivery-order-id <id>]
106
106
  toloka project untrack <pipeline|dataset> <name> [--confirm]
107
107
  toloka delivery-order list
108
+ toloka audience specialization list [--json]
108
109
  toloka init
109
110
  toloka import [projectId]
110
111
  toloka check [pipeline] [--node <name-or-id>] [--json] [--watch]
@@ -134,8 +135,8 @@ toloka model create <name> --base <base-model-id> [--description <text>] [--json
134
135
  toloka model archive <name-or-id> [--json]
135
136
  toloka training list [--json]
136
137
  toloka training get <name-or-id> [--json]
137
- toloka training create <name> [--method sft|gisting] (--base-model <id> | --model-version <id>) --dataset <id> [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
138
- toloka training update <name-or-id> [--base-model <id> | --model-version <id>] [--dataset <id>] [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
138
+ toloka training create <name> [--method sft|gisting] (--base-model <id> | --model-version <id>) --dataset <id> [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64|1/4|1/8|1/16|1/32] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
139
+ toloka training update <name-or-id> [--base-model <id> | --model-version <id>] [--dataset <id>] [--train-filter field=value] [--validation-dataset <id> [--validation-filter field=value]] [--prompt-file <path>] [--lora-rank 8|16|32 | --gist-tokens 8|32|64|1/4|1/8|1/16|1/32] [--epochs 1..5] [--learning-rate <rate>] [--batch-size 8|16|32|64] [--max-sequence-length <tokens>] [--json]
139
140
  toloka training cost <name-or-id> [--idempotency-key <key>] [--json]
140
141
  toloka training run <name-or-id> [--estimate-file <path>] [--version-name <name>] [--idempotency-key <key>] [--json]
141
142
  toloka training runs <name-or-id> [--json]
@@ -156,6 +157,8 @@ Resolve the intended platform project before `import`, `plan`, or `apply`; use a
156
157
 
157
158
  `toloka project url` prints only the selected project's platform UI URL. Use it when the user needs a working link to inspect the live project.
158
159
 
160
+ `toloka audience specialization list` prints the global specialization catalog: `ID`, `NAME`, and `EXPERTS` columns sorted by name (`--json` for the array). Run it before setting `audience.specializations` on a node, pick entries by name, and copy `ID` into `qualificationId` and `NAME` into `value`; never invent a `qualificationId`. `EXPERTS` counts ID-verified experts currently eligible for tasks; a `0` means the id is valid but nobody currently qualifies, so prefer another specialization or widen the audience.
161
+
159
162
  `toloka pipeline cost [name] [--item-limit <n>]` forecasts what a run of a live, validated pipeline would bill. It does not start a run or change the graph. If any billed node is marked `skipped`, the displayed total is incomplete and must not be presented as the pipeline price. Compute and label a labor floor for each skipped billed node as `items × pricePerTask × annotations per item`, using `1` for generation and `overlap` for quorum. Also report `maxEntities`, quality-criteria count, and only exclusions applicable to the authored QA and workflow. Apply accepting a rate does not prove its final billed value.
160
163
 
161
164
  ## Manage model checkpoints
@@ -164,9 +167,9 @@ The global Base Model Catalog is read-only and uses `toloka base-model`. `base-m
164
167
 
165
168
  ## Train a model
166
169
 
167
- `toloka training create` requires one source (`--base-model` or `--model-version`) and a training Dataset. The output Model is created on the first Training Run from the Training name, or bound from an existing Model Version source.
170
+ `toloka training create` requires one source (`--base-model` or `--model-version`) and a training Dataset. A `--model-version` source must be a LoRA adapter Model Version (one produced by fine-tuning) and works for both methods — SFT continues the adapter, gisting merges it and trains gist tokens over it; a full-weights version is rejected with "Training from a Model Version requires a LoRA adapter source". The first Training Run creates a new output Model named after the Training; a source Model Version is only the training parent, never the output binding.
168
171
 
169
- Hyperparameters are optional flags on `training create` and `training update`: `--epochs 1..5` (default 3), `--learning-rate` (SFT 0.00001–0.001, default 0.00015; gisting 0.001–0.3, default 0.03), `--batch-size 8|16|32|64` (default 8; sequences per optimizer step across all GPUs) and `--max-sequence-length 64..16384` (default 12288 for SFT, 3072 for gisting) apply to both methods; `--lora-rank 8|16|32` (default 16) is SFT-only and `--gist-tokens 8|32|64` (default 32) is gisting-only — passing one to the other method fails before any request. `--regime` and `--eval-steps` no longer exist. `training update` has no `--method` flag: the method stays as created, and every flag you omit keeps its current value. `training cost` is blocked when the longest example exceeds `--max-sequence-length` or when the training selection leaves fewer rows than `--batch-size` after the 10% holdout.
172
+ Hyperparameters are optional flags on `training create` and `training update`: `--epochs 1..5` (default 3), `--learning-rate` (SFT 0.00001–0.001, default 0.00015; gisting 0.001–0.3, default 0.03), `--batch-size 8|16|32|64` (default 8; sequences per optimizer step across all GPUs) and `--max-sequence-length 64..16384` (default 12288 for SFT, 3072 for gisting) apply to both methods; `--lora-rank 8|16|32` (default 16) is SFT-only and `--gist-tokens` (default 32) is gisting-only — passing one to the other method fails before any request. `--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`), which the run resolves to `ceil(prompt tokens / N)` clamped to 8..256. `--regime` and `--eval-steps` no longer exist. `training update` has no `--method` flag: the method stays as created, and every flag you omit keeps its current value. `training cost` is blocked when the longest example exceeds `--max-sequence-length` or when the training selection leaves fewer rows than `--batch-size` after the 10% holdout.
170
173
 
171
174
  Use `training cost` to validate inputs and show the maximum charge before `training run`. A blocked estimate exits 1 and lists the issues on stderr instead of printing the estimate; fix them and recalculate. `training run` accepts that ready estimate JSON through `--estimate-file`; without it, the command calculates a fresh ready estimate itself before creating the run. `--version-name` defaults to the Training name; pass it when a Model Version with that name already exists. Use `training status`, `training logs`, `training metrics`, `training resume`, and `training cancel` with the returned Training Run ID. `training metrics` lists each metric's latest value while the run is still training; `--key` prints one metric's point history instead.
172
175
 
@@ -83,7 +83,7 @@ toloka model versions <model-id> --json
83
83
 
84
84
  For a Base Model, compare upstream documentation, user-provided benchmarks, and prior results for task and language fit, data volume, quality, training budget, and serving latency or deployment constraints. Model size alone is not a quality decision; a smaller model is a useful cost and latency baseline when the task permits it, not a mandatory default. Use `base-model get` only to verify the selected catalog ID, upstream model, and pinned revision; it does not establish those broader capabilities.
85
85
 
86
- For a Model Version, verify the exact ID and revision under its project-owned Model, and record the owning Model's Base Model and the Version's runtime base from JSON. If those identities conflict, report the conflict rather than guessing or substituting. Use `--model-version` only for that existing version. The ready cost estimate is the concrete final check that the source type, underlying Base Model, method, and data are supported together.
86
+ For a Model Version, verify the exact ID and revision under its project-owned Model, and record the owning Model's Base Model and the Version's runtime base from JSON. If those identities conflict, report the conflict rather than guessing or substituting. Use `--model-version` only for that existing version, and only for a LoRA adapter Model Version (one produced by fine-tuning) — a full-weights version is rejected with "Training from a Model Version requires a LoRA adapter source". The ready cost estimate is the concrete final check that the source type, underlying Base Model, method, and data are supported together.
87
87
 
88
88
  ### 4. Reuse or create the draft
89
89
 
@@ -145,6 +145,8 @@ toloka training metrics <training-run-id> --json
145
145
 
146
146
  Resume only after the user confirms a billing block is resolved. Cancel only on explicit request.
147
147
 
148
+ 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.
149
+
148
150
  For a completed run, verify the observed output and download only when requested:
149
151
 
150
152
  ```sh
@@ -24,12 +24,13 @@ Check the runtime or CLI only when its state is not already known:
24
24
  ```sh
25
25
  bun --version
26
26
  toloka --version
27
+ toloka dataset --help
27
28
  ```
28
29
 
29
- The runbooks use the `preview` channel of `@toloka-platform/sdk`, so `toloka --version` must print `0.2.0-preview.4` or newer. If `toloka` is unavailable or comes from another channel, install the preview version:
30
+ The runbooks require a stable Toloka CLI release at version `0.2.0` or newer: `toloka --version` must print `0.2.0` or a newer version with no prerelease suffix, and `toloka dataset --help` must list `create`. If either command is unavailable, the version is older or prerelease, or the capability check fails, install the latest stable version:
30
31
 
31
32
  ```sh
32
- curl -fsSL https://platform.toloka.ai/cli/install.sh | TOLOKA_CLI_CHANNEL=preview sh
33
+ curl -fsSL https://platform.toloka.ai/cli/install.sh | sh
33
34
  ```
34
35
 
35
36
  Never request an API key in chat. Inspect the active identity with:
@@ -90,7 +90,7 @@ toloka model versions <model-id> --json
90
90
 
91
91
  For a Base Model, compare available evidence about prompt and language fit, prior quality, data volume, desired compression fidelity, training budget, and serving latency or deployment constraints. Model size alone is not a quality decision; a smaller model is a useful cost and latency baseline when the task permits it, not a mandatory default. Verify the selected catalog ID, upstream model, and pinned revision with `base-model get`, and consult upstream documentation or user-provided evidence for capabilities the catalog does not expose.
92
92
 
93
- For a Model Version, verify the exact ID and revision under its project-owned Model, and record the owning Model's Base Model and the Version's runtime base from JSON. If those identities conflict, report the conflict rather than guessing or substituting. Use `--model-version` only for that existing version. The ready cost estimate is the concrete final check that the source type, underlying Base Model, method, prompt, and data are supported together.
93
+ Gisting starts either from a catalog Base Model or, to compress a prompt for a model you already fine-tuned, from that model's LoRA adapter Model Version via `--model-version` (the adapter is merged into the base and the gist tokens are trained over the fine-tuned weights). Because gisting publishes a full model, it is limited to the qwen3-4b and qwen3-8b tiers, and a `--model-version` source must be a LoRA adapter version (a full-weights version is rejected).
94
94
 
95
95
  ### 4. Reuse or create the draft
96
96
 
@@ -113,9 +113,9 @@ toloka training create "<training-name>" \
113
113
  --json
114
114
  ```
115
115
 
116
- 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>`.
116
+ 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>`.
117
117
 
118
- Preserve requested hyperparameters. The current CLI uses `--gist-tokens 8|32|64` (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; 8 gist tokens favor compression for simple prompts, while 64 may help when 32 loses holdout accuracy. 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
+ 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.
119
119
 
120
120
  Verify the saved method, exact source, prompt file, selections, filters, and configuration with `toloka training get <training-id> --json`.
121
121
 
@@ -154,6 +154,8 @@ toloka training metrics <training-run-id> --json
154
154
 
155
155
  Resume only after the user confirms a billing block is resolved. Cancel only on explicit request.
156
156
 
157
+ 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.
158
+
157
159
  For a completed run, verify the observed output and download only when requested:
158
160
 
159
161
  ```sh
@@ -26,7 +26,7 @@ The CLI exits 1 with `Potato API request failed with status 500`. The same comma
26
26
 
27
27
  ## Environment
28
28
 
29
- - toloka CLI 0.2.0-preview.3 (`toloka --version`), Bun 1.4.0, macOS 15
29
+ - toloka CLI 0.2.0 (`toloka --version`), Bun 1.4.0, macOS 15
30
30
  - Platform: https://platform.toloka.ai
31
31
 
32
32
  ## Redactions
@@ -10,7 +10,10 @@ import {
10
10
  createVirtualTypeScriptEnvironment,
11
11
  } from "./typescript-vfs.js";
12
12
 
13
- const tsLibDirectory = path.dirname(ts.getDefaultLibFilePath({ target: ts.ScriptTarget.Latest }));
13
+ const tsLibDirectory =
14
+ Reflect.get(globalThis, "Bun")?.isStandaloneExecutable === true
15
+ ? path.join(path.dirname(process.argv[1]!), "typescript-lib")
16
+ : path.dirname(ts.getDefaultLibFilePath({ target: ts.ScriptTarget.Latest }));
14
17
 
15
18
  const BLOCK_MARKERS = {
16
19
  data: "DATA_INJECTION",
@@ -93,6 +93,7 @@ const COMMAND_GROUPS: Readonly<Record<string, CommandGroup>> = {
93
93
  },
94
94
  dataset: { list: true, create: true, fields: true, load: true, upload: true },
95
95
  "delivery-order": { list: true },
96
+ audience: { specialization: { list: true } },
96
97
  training: {
97
98
  list: true,
98
99
  get: true,
@@ -0,0 +1,31 @@
1
+ import type { PotatoClient } from "../client";
2
+ import type { Specialization } from "../../openapi/gen/models";
3
+ import { formatTable, type TableIo, writeOutput } from "./table";
4
+
5
+ type AudienceApi = Pick<PotatoClient, "audience">;
6
+
7
+ export const listSpecializations = async (
8
+ client: AudienceApi,
9
+ input: { json: boolean },
10
+ io: TableIo,
11
+ ): Promise<void> => {
12
+ const specializations: Specialization[] = [];
13
+ for await (const specialization of client.audience.specializations.listAll()) {
14
+ specializations.push(specialization);
15
+ }
16
+ writeOutput(
17
+ io,
18
+ input.json,
19
+ specializations,
20
+ specializations.length === 0
21
+ ? "No specializations available."
22
+ : formatTable([
23
+ ["ID", "NAME", "EXPERTS"],
24
+ ...specializations.map((specialization) => [
25
+ specialization.id,
26
+ specialization.name,
27
+ String(specialization.expertsCount),
28
+ ]),
29
+ ]),
30
+ );
31
+ };