@toloka-platform/sdk 0.2.0-preview.2 → 0.2.0-preview.4

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 (110) hide show
  1. package/README.md +10 -4
  2. package/dist/cli/toloka.js +162 -154
  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 +18 -1
  7. package/docs/cli-v2.md +6 -4
  8. package/docs/cli.md +58 -11
  9. package/docs/getting-started.md +3 -3
  10. package/docs/limitations.md +1 -1
  11. package/docs/testing.md +1 -1
  12. package/docs/troubleshooting.md +1 -1
  13. package/examples/face-image-collection/README.md +2 -2
  14. package/openapi/gen/api.ts +78 -0
  15. package/openapi/gen/models/baseModel.ts +1 -0
  16. package/openapi/gen/models/checkReport.ts +2 -1
  17. package/openapi/gen/models/checkReportAnyOfTwoseven.ts +5 -0
  18. package/openapi/gen/models/checkReportAnyOfTwosevenResultsItem.ts +6 -0
  19. package/openapi/gen/models/checkReportAnyOfTwosevenResultsItemVerdict.ts +2 -0
  20. package/openapi/gen/models/currentUser.ts +3 -0
  21. package/openapi/gen/models/currentUserTeamsItem.ts +6 -0
  22. package/openapi/gen/models/deliveryOrder.ts +9 -0
  23. package/openapi/gen/models/deliveryOrderClientName.ts +2 -0
  24. package/openapi/gen/models/getTrainingRunMetricHistoryParams.ts +4 -0
  25. package/openapi/gen/models/gistingTrainingConfiguration.ts +6 -2
  26. package/openapi/gen/models/gistingTrainingConfigurationBatchSize.ts +2 -0
  27. package/openapi/gen/models/gistingTrainingConfigurationGistTokens.ts +2 -0
  28. package/openapi/gen/models/gistingTrainingConfigurationInput.ts +6 -2
  29. package/openapi/gen/models/gistingTrainingConfigurationInputBatchSize.ts +2 -0
  30. package/openapi/gen/models/gistingTrainingConfigurationInputGistTokens.ts +2 -0
  31. package/openapi/gen/models/index.ts +28 -4
  32. package/openapi/gen/models/listDeliveryOrders200.ts +5 -0
  33. package/openapi/gen/models/sftTrainingConfiguration.ts +6 -3
  34. package/openapi/gen/models/sftTrainingConfigurationBatchSize.ts +2 -0
  35. package/openapi/gen/models/sftTrainingConfigurationInput.ts +6 -3
  36. package/openapi/gen/models/sftTrainingConfigurationInputBatchSize.ts +2 -0
  37. package/openapi/gen/models/sftTrainingConfigurationInputLoraRank.ts +2 -0
  38. package/openapi/gen/models/sftTrainingConfigurationLoraRank.ts +2 -0
  39. package/openapi/gen/models/trainingRunMetricHistory.ts +9 -0
  40. package/openapi/gen/models/trainingRunMetricHistoryMetric.ts +2 -0
  41. package/openapi/gen/models/trainingRunMetricHistoryPointsItem.ts +9 -0
  42. package/openapi/gen/models/trainingRunMetricHistoryPointsItemNonFinite.ts +2 -0
  43. package/openapi/gen/models/trainingRunMetricHistoryPointsItemValue.ts +2 -0
  44. package/openapi/gen/models/trainingRunMetrics.ts +9 -0
  45. package/openapi/gen/models/trainingRunMetricsMetricsItem.ts +8 -0
  46. package/openapi/gen/models/trainingRunMetricsMetricsItemLatest.ts +9 -0
  47. package/openapi/gen/models/trainingRunMetricsMetricsItemLatestNonFinite.ts +2 -0
  48. package/openapi/gen/models/trainingRunMetricsMetricsItemLatestValue.ts +2 -0
  49. package/openapi/gen/models/trainingRunMetricsMetricsItemMetric.ts +2 -0
  50. package/openapi/gen/models/trainingRunMetricsUnavailableReason.ts +2 -0
  51. package/package.json +2 -2
  52. package/skills/catalog.json +55 -7
  53. package/skills/toloka-build/SKILL.md +35 -21
  54. package/skills/toloka-build/references/node-semantics.md +13 -11
  55. package/skills/toloka-build/references/workflow-and-cli.md +31 -20
  56. package/skills/toloka-fine-tuning/SKILL.md +155 -0
  57. package/skills/toloka-get-started/SKILL.md +70 -0
  58. package/skills/toloka-gisting/SKILL.md +166 -0
  59. package/skills/toloka-report-issue/references/report-template.md +1 -1
  60. package/src/authoring/index.ts +14 -0
  61. package/src/checks/task-ui-typecheck.ts +12 -10
  62. package/src/cli/analytics.ts +88 -15
  63. package/src/cli/auth.ts +93 -21
  64. package/src/cli/auto-update.ts +36 -39
  65. package/src/cli/check.ts +88 -39
  66. package/src/cli/cli-entry.ts +3 -2
  67. package/src/cli/cli-error.ts +43 -0
  68. package/src/cli/commands/auth.ts +89 -0
  69. package/src/cli/commands/config.ts +28 -0
  70. package/src/cli/commands/dataset.ts +85 -0
  71. package/src/cli/commands/delivery-order.ts +18 -0
  72. package/src/cli/commands/models.ts +121 -0
  73. package/src/cli/commands/pipeline.ts +131 -0
  74. package/src/cli/commands/project.ts +168 -0
  75. package/src/cli/commands/report.ts +43 -0
  76. package/src/cli/commands/secret.ts +40 -0
  77. package/src/cli/commands/skill.ts +36 -0
  78. package/src/cli/commands/source.ts +204 -0
  79. package/src/cli/commands/status.ts +17 -0
  80. package/src/cli/commands/training.ts +261 -0
  81. package/src/cli/commands/version.ts +14 -0
  82. package/src/cli/config.ts +7 -8
  83. package/src/cli/context.ts +251 -0
  84. package/src/cli/credentials.ts +12 -4
  85. package/src/cli/data.ts +96 -34
  86. package/src/cli/delivery-orders.ts +47 -0
  87. package/src/cli/environment.ts +26 -0
  88. package/src/cli/file-system.ts +6 -2
  89. package/src/cli/format-error.ts +45 -2
  90. package/src/cli/init.ts +14 -11
  91. package/src/cli/models.ts +43 -12
  92. package/src/cli/program.ts +120 -1347
  93. package/src/cli/project-context.ts +126 -43
  94. package/src/cli/project.ts +80 -28
  95. package/src/cli/report.ts +24 -9
  96. package/src/cli/runs.ts +33 -8
  97. package/src/cli/sdk-version.ts +38 -0
  98. package/src/cli/settings.ts +13 -5
  99. package/src/cli/skill.ts +67 -24
  100. package/src/cli/source.ts +3 -2
  101. package/src/cli/terminal-io.ts +110 -0
  102. package/src/cli/trainings.ts +242 -57
  103. package/src/cli/version.ts +3 -3
  104. package/src/client.ts +21 -9
  105. package/src/importer.ts +32 -2
  106. package/src/transport.ts +13 -1
  107. package/openapi/gen/models/gistingTrainingConfigurationInputRegime.ts +0 -2
  108. package/openapi/gen/models/gistingTrainingConfigurationRegime.ts +0 -2
  109. package/openapi/gen/models/sftTrainingConfigurationInputRegime.ts +0 -2
  110. package/openapi/gen/models/sftTrainingConfigurationRegime.ts +0 -2
@@ -55,6 +55,9 @@ export * from './checkReportAnyOfTwoone';
55
55
  export * from './checkReportAnyOfTwooneFindingsItem';
56
56
  export * from './checkReportAnyOfTwooneFindingsItemFlag';
57
57
  export * from './checkReportAnyOfTwooneFindingsItemSettingName';
58
+ export * from './checkReportAnyOfTwoseven';
59
+ export * from './checkReportAnyOfTwosevenResultsItem';
60
+ export * from './checkReportAnyOfTwosevenResultsItemVerdict';
58
61
  export * from './checkRunId';
59
62
  export * from './codeNode';
60
63
  export * from './codeNodeSettings';
@@ -107,6 +110,7 @@ export * from './createTrainingRunBody';
107
110
  export * from './createdDatasetFields';
108
111
  export * from './currentUser';
109
112
  export * from './currentUserEmail';
113
+ export * from './currentUserTeamsItem';
110
114
  export * from './dataset';
111
115
  export * from './datasetExportReport';
112
116
  export * from './datasetExportReportErrorsItem';
@@ -127,6 +131,8 @@ export * from './datasetItemId';
127
131
  export * from './datasetProfile';
128
132
  export * from './datasetProfileStamp';
129
133
  export * from './datasetProfileStampName';
134
+ export * from './deliveryOrder';
135
+ export * from './deliveryOrderClientName';
130
136
  export * from './estimatePipelineCostBody';
131
137
  export * from './estimatePipelineCostBodyItemFilter';
132
138
  export * from './estimatePipelineCostBodyItemFilterFieldSourcesItem';
@@ -257,10 +263,13 @@ export * from './generationNodeSettingsSmartSearchAnyOfProjectDescription';
257
263
  export * from './generationNodeSettingsUi';
258
264
  export * from './getDatasetInferredFields200';
259
265
  export * from './getTrainingRunLogsParams';
266
+ export * from './getTrainingRunMetricHistoryParams';
260
267
  export * from './gistingTrainingConfiguration';
268
+ export * from './gistingTrainingConfigurationBatchSize';
269
+ export * from './gistingTrainingConfigurationGistTokens';
261
270
  export * from './gistingTrainingConfigurationInput';
262
- export * from './gistingTrainingConfigurationInputRegime';
263
- export * from './gistingTrainingConfigurationRegime';
271
+ export * from './gistingTrainingConfigurationInputBatchSize';
272
+ export * from './gistingTrainingConfigurationInputGistTokens';
264
273
  export * from './importPipelineBody';
265
274
  export * from './inferredField';
266
275
  export * from './inferredFieldJsonSchema';
@@ -276,6 +285,7 @@ export * from './listDatasetFields200';
276
285
  export * from './listDatasetFieldsParams';
277
286
  export * from './listDatasetItems200';
278
287
  export * from './listDatasetItemsParams';
288
+ export * from './listDeliveryOrders200';
279
289
  export * from './listModelVersions200';
280
290
  export * from './listModelVersionsParams';
281
291
  export * from './listPipelineChecks200';
@@ -814,9 +824,11 @@ export * from './sampleJobStatus';
814
824
  export * from './sampleResult';
815
825
  export * from './setProjectSecretBody';
816
826
  export * from './sftTrainingConfiguration';
827
+ export * from './sftTrainingConfigurationBatchSize';
817
828
  export * from './sftTrainingConfigurationInput';
818
- export * from './sftTrainingConfigurationInputRegime';
819
- export * from './sftTrainingConfigurationRegime';
829
+ export * from './sftTrainingConfigurationInputBatchSize';
830
+ export * from './sftTrainingConfigurationInputLoraRank';
831
+ export * from './sftTrainingConfigurationLoraRank';
820
832
  export * from './training';
821
833
  export * from './trainingArchivedAt';
822
834
  export * from './trainingConfiguration';
@@ -961,6 +973,18 @@ export * from './trainingRunLogsEntriesItem';
961
973
  export * from './trainingRunLogsEntriesItemLevel';
962
974
  export * from './trainingRunLogsNextCursor';
963
975
  export * from './trainingRunMessage';
976
+ export * from './trainingRunMetricHistory';
977
+ export * from './trainingRunMetricHistoryMetric';
978
+ export * from './trainingRunMetricHistoryPointsItem';
979
+ export * from './trainingRunMetricHistoryPointsItemNonFinite';
980
+ export * from './trainingRunMetricHistoryPointsItemValue';
981
+ export * from './trainingRunMetrics';
982
+ export * from './trainingRunMetricsMetricsItem';
983
+ export * from './trainingRunMetricsMetricsItemLatest';
984
+ export * from './trainingRunMetricsMetricsItemLatestNonFinite';
985
+ export * from './trainingRunMetricsMetricsItemLatestValue';
986
+ export * from './trainingRunMetricsMetricsItemMetric';
987
+ export * from './trainingRunMetricsUnavailableReason';
964
988
  export * from './trainingRunOutputModelVersionRevision';
965
989
  export * from './trainingRunProgress';
966
990
  export * from './trainingRunProgressAnyOf';
@@ -0,0 +1,5 @@
1
+ import type { DeliveryOrder } from './deliveryOrder';
2
+
3
+ export type ListDeliveryOrders200 = {
4
+ deliveryOrders: DeliveryOrder[];
5
+ };
@@ -1,13 +1,16 @@
1
1
  import type { TrainingModelSource } from './trainingModelSource';
2
2
  import type { TrainingDatasetSelection } from './trainingDatasetSelection';
3
- import type { SftTrainingConfigurationRegime } from './sftTrainingConfigurationRegime';
3
+ import type { SftTrainingConfigurationLoraRank } from './sftTrainingConfigurationLoraRank';
4
+ import type { SftTrainingConfigurationBatchSize } from './sftTrainingConfigurationBatchSize';
4
5
 
5
6
  export interface SftTrainingConfiguration {
6
7
  method: 'sft';
7
8
  source: TrainingModelSource;
8
9
  training: TrainingDatasetSelection;
9
10
  validation?: TrainingDatasetSelection;
10
- regime: SftTrainingConfigurationRegime;
11
+ loraRank: SftTrainingConfigurationLoraRank;
11
12
  epochs: number;
12
- evalSteps: number;
13
+ learningRate: number;
14
+ batchSize: SftTrainingConfigurationBatchSize;
15
+ maxSequenceLength: number;
13
16
  }
@@ -0,0 +1,2 @@
1
+
2
+ export type SftTrainingConfigurationBatchSize = 8 | 16 | 32 | 64;
@@ -1,13 +1,16 @@
1
1
  import type { TrainingModelSource } from './trainingModelSource';
2
2
  import type { TrainingDatasetSelectionInput } from './trainingDatasetSelectionInput';
3
- import type { SftTrainingConfigurationInputRegime } from './sftTrainingConfigurationInputRegime';
3
+ import type { SftTrainingConfigurationInputLoraRank } from './sftTrainingConfigurationInputLoraRank';
4
+ import type { SftTrainingConfigurationInputBatchSize } from './sftTrainingConfigurationInputBatchSize';
4
5
 
5
6
  export interface SftTrainingConfigurationInput {
6
7
  method: 'sft';
7
8
  source: TrainingModelSource;
8
9
  training: TrainingDatasetSelectionInput;
9
10
  validation?: TrainingDatasetSelectionInput;
10
- regime?: SftTrainingConfigurationInputRegime;
11
+ loraRank?: SftTrainingConfigurationInputLoraRank;
11
12
  epochs?: number;
12
- evalSteps?: number;
13
+ learningRate?: number;
14
+ batchSize?: SftTrainingConfigurationInputBatchSize;
15
+ maxSequenceLength?: number;
13
16
  }
@@ -0,0 +1,2 @@
1
+
2
+ export type SftTrainingConfigurationInputBatchSize = 8 | 16 | 32 | 64;
@@ -0,0 +1,2 @@
1
+
2
+ export type SftTrainingConfigurationInputLoraRank = 8 | 16 | 32;
@@ -0,0 +1,2 @@
1
+
2
+ export type SftTrainingConfigurationLoraRank = 8 | 16 | 32;
@@ -0,0 +1,9 @@
1
+ import type { TrainingRunMetricHistoryMetric } from './trainingRunMetricHistoryMetric';
2
+ import type { TrainingRunMetricHistoryPointsItem } from './trainingRunMetricHistoryPointsItem';
3
+
4
+ export interface TrainingRunMetricHistory {
5
+ key: string;
6
+ metric: TrainingRunMetricHistoryMetric;
7
+ points: TrainingRunMetricHistoryPointsItem[];
8
+ truncated: boolean;
9
+ }
@@ -0,0 +1,2 @@
1
+
2
+ export type TrainingRunMetricHistoryMetric = 'training_loss' | 'validation_loss' | 'learning_rate' | 'training_token_accuracy' | 'validation_token_accuracy' | null;
@@ -0,0 +1,9 @@
1
+ import type { TrainingRunMetricHistoryPointsItemValue } from './trainingRunMetricHistoryPointsItemValue';
2
+ import type { TrainingRunMetricHistoryPointsItemNonFinite } from './trainingRunMetricHistoryPointsItemNonFinite';
3
+
4
+ export type TrainingRunMetricHistoryPointsItem = {
5
+ step: number;
6
+ timestamp: number;
7
+ value: TrainingRunMetricHistoryPointsItemValue;
8
+ nonFinite: TrainingRunMetricHistoryPointsItemNonFinite;
9
+ };
@@ -0,0 +1,2 @@
1
+
2
+ export type TrainingRunMetricHistoryPointsItemNonFinite = 'nan' | 'positive_infinity' | 'negative_infinity' | null;
@@ -0,0 +1,2 @@
1
+
2
+ export type TrainingRunMetricHistoryPointsItemValue = number | null;
@@ -0,0 +1,9 @@
1
+ import type { TrainingRunMetricsUnavailableReason } from './trainingRunMetricsUnavailableReason';
2
+ import type { TrainingRunMetricsMetricsItem } from './trainingRunMetricsMetricsItem';
3
+
4
+ export interface TrainingRunMetrics {
5
+ available: boolean;
6
+ unavailableReason: TrainingRunMetricsUnavailableReason;
7
+ truncated: boolean;
8
+ metrics: TrainingRunMetricsMetricsItem[];
9
+ }
@@ -0,0 +1,8 @@
1
+ import type { TrainingRunMetricsMetricsItemMetric } from './trainingRunMetricsMetricsItemMetric';
2
+ import type { TrainingRunMetricsMetricsItemLatest } from './trainingRunMetricsMetricsItemLatest';
3
+
4
+ export type TrainingRunMetricsMetricsItem = {
5
+ key: string;
6
+ metric: TrainingRunMetricsMetricsItemMetric;
7
+ latest: TrainingRunMetricsMetricsItemLatest;
8
+ };
@@ -0,0 +1,9 @@
1
+ import type { TrainingRunMetricsMetricsItemLatestValue } from './trainingRunMetricsMetricsItemLatestValue';
2
+ import type { TrainingRunMetricsMetricsItemLatestNonFinite } from './trainingRunMetricsMetricsItemLatestNonFinite';
3
+
4
+ export type TrainingRunMetricsMetricsItemLatest = {
5
+ step: number;
6
+ timestamp: number;
7
+ value: TrainingRunMetricsMetricsItemLatestValue;
8
+ nonFinite: TrainingRunMetricsMetricsItemLatestNonFinite;
9
+ };
@@ -0,0 +1,2 @@
1
+
2
+ export type TrainingRunMetricsMetricsItemLatestNonFinite = 'nan' | 'positive_infinity' | 'negative_infinity' | null;
@@ -0,0 +1,2 @@
1
+
2
+ export type TrainingRunMetricsMetricsItemLatestValue = number | null;
@@ -0,0 +1,2 @@
1
+
2
+ export type TrainingRunMetricsMetricsItemMetric = 'training_loss' | 'validation_loss' | 'learning_rate' | 'training_token_accuracy' | 'validation_token_accuracy' | null;
@@ -0,0 +1,2 @@
1
+
2
+ export type TrainingRunMetricsUnavailableReason = 'not_configured' | 'unresolved' | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toloka-platform/sdk",
3
- "version": "0.2.0-preview.2",
3
+ "version": "0.2.0-preview.4",
4
4
  "private": false,
5
5
  "description": "Beta. Build, inspect, and operate Toloka pipeline projects as TypeScript source. The public API may change.",
6
6
  "license": "Apache-2.0",
@@ -73,6 +73,6 @@
73
73
  }
74
74
  },
75
75
  "engines": {
76
- "bun": "1.4.0"
76
+ "bun": ">=1.4.0"
77
77
  }
78
78
  }
@@ -3,18 +3,16 @@
3
3
  {
4
4
  "id": "toloka-build",
5
5
  "name": "Build Toloka pipelines as code",
6
- "description": "Onboard users and build, test, inspect, or change Toloka platform pipeline projects as TypeScript source with @toloka-platform/sdk, toloka check, and toloka apply. Use when the user wants to get started, create, adopt, inspect, plan, apply, test, check, or run a pipeline project as code.",
6
+ "description": "Build, test, inspect, or change Toloka platform pipeline projects as TypeScript source with @toloka-platform/sdk, toloka check, and toloka apply. Use when the user has selected pipeline authoring or wants to inspect, plan, apply, test, check, or run a pipeline project as code.",
7
7
  "tags": [
8
8
  "pipelines",
9
9
  "authoring",
10
10
  "sdk",
11
- "onboarding",
12
- "getting-started",
13
11
  "testing",
14
12
  "checks"
15
13
  ],
16
- "version": "0.2.0-preview.2",
17
- "digest": "0777193859ccc60959ba91c2733e8d1631d1b4c89f313c9989ed6c67b40f1c5a",
14
+ "version": "0.2.0-preview.4",
15
+ "digest": "2d27360563da6ff5ef41d264982d89232087cf7c76393022c83a66c5301752b3",
18
16
  "files": [
19
17
  "SKILL.md",
20
18
  "references/node-semantics.md",
@@ -31,12 +29,62 @@
31
29
  "bug",
32
30
  "report"
33
31
  ],
34
- "version": "0.2.0-preview.2",
35
- "digest": "9faa9ed606cdb55ca701d2662f8633daebe49b865ff9b8f4cf9bb7d9b621f675",
32
+ "version": "0.2.0-preview.4",
33
+ "digest": "76229bae596f8a1722ce7fc55bea3dd66698df5b61baa31f6cb98ca2b5fa03e8",
36
34
  "files": [
37
35
  "SKILL.md",
38
36
  "references/report-template.md"
39
37
  ]
38
+ },
39
+ {
40
+ "id": "toloka-get-started",
41
+ "name": "Get started with Toloka",
42
+ "description": "Orient a Toloka session to the user's outcome and safely reuse or establish the needed CLI, authentication, project, workflow, and approval context. Use when the user is new to Toloka, asks what to do first, or has not selected a pipeline, fine-tuning, or gisting workflow.",
43
+ "tags": [
44
+ "toloka",
45
+ "onboarding",
46
+ "getting-started",
47
+ "agent"
48
+ ],
49
+ "version": "0.2.0-preview.4",
50
+ "digest": "f86ba45aba0bf2b06bc02b65c6f3dbb7b9b4cb28630191bafa62b6e627448138",
51
+ "files": [
52
+ "SKILL.md"
53
+ ]
54
+ },
55
+ {
56
+ "id": "toloka-fine-tuning",
57
+ "name": "Fine-tune a model with Toloka",
58
+ "description": "Create, estimate, start, monitor, and verify a project-owned supervised fine-tuning Training through the Toloka CLI. Use when the user wants to adapt a base model or existing Model Version from labeled conversations.",
59
+ "tags": [
60
+ "toloka",
61
+ "training",
62
+ "fine-tuning",
63
+ "sft",
64
+ "models"
65
+ ],
66
+ "version": "0.2.0-preview.4",
67
+ "digest": "81c43af9e78e1df322085dd2ec923e85a7be0d084c689906aa5db6cdbd03c9e3",
68
+ "files": [
69
+ "SKILL.md"
70
+ ]
71
+ },
72
+ {
73
+ "id": "toloka-gisting",
74
+ "name": "Compress a prompt with gisting",
75
+ "description": "Create, estimate, start, monitor, and verify a project-owned prompt-gisting Training through the Toloka CLI. Use when the user wants a compact prompt representation from example conversations and a prompt file.",
76
+ "tags": [
77
+ "toloka",
78
+ "training",
79
+ "gisting",
80
+ "prompt",
81
+ "models"
82
+ ],
83
+ "version": "0.2.0-preview.4",
84
+ "digest": "ee30f006d8f7995a825db5e7c74732e35517d88b43a4f6671d6439f1c333c815",
85
+ "files": [
86
+ "SKILL.md"
87
+ ]
40
88
  }
41
89
  ]
42
90
  }
@@ -1,22 +1,31 @@
1
1
  ---
2
2
  name: toloka-build
3
- description: Onboard users and build, test, inspect, or change Toloka platform pipeline projects as TypeScript source with @toloka-platform/sdk, toloka check, and toloka apply. Use when the user wants to get started, create, adopt, inspect, plan, apply, test, check, or run a pipeline project as code.
3
+ description: Build, test, inspect, or change Toloka platform pipeline projects as TypeScript source with @toloka-platform/sdk, toloka check, and toloka apply. Use when the user has selected pipeline authoring or wants to inspect, plan, apply, test, check, or run a pipeline project as code.
4
4
  ---
5
5
 
6
6
  # Build Toloka pipelines as code
7
7
 
8
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.
9
9
 
10
- Use this skill when the user wants to get started or to create, inspect, test, or change a Toloka pipeline project as code. Work in the project source tree; do not translate the request into direct platform API calls.
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
 
12
- ## Guide a first-time user
12
+ ## Enter the pipeline workflow
13
13
 
14
- When the user asks to get started or points to `https://platform.toloka.ai/agents/data-labeling.md`, read that guide before acting. The guide owns the session order and its user checkpoints. This skill owns authoring semantics, local test requirements, recovery, and evidence reporting.
14
+ For first-time setup or help choosing a workflow, install and read `toloka-get-started` and consult the matching public runbook. Use its onboarding steps where needed; an existing project or a focused inspection request does not need the full first-run journey. A demo is useful for learning, not a prerequisite for the user's own task.
15
15
 
16
- Do not replace the guide's quick demo with another example, and do not run the demo when the user chooses their own task. Never cross its API-key, project-creation, plan, or run-cost checkpoint without the user's required action or approval.
16
+ Use your expertise for routine choices, and briefly explain decisions that affect quality, cost, or maintainability. Ask a focused question when missing requirements or conflicting constraints would materially change the result; do not ask the user to choose SDK mechanics you can determine yourself. Preserve explicit requirements and existing project intent. Credentials belong in the user's `toloka login` prompt, paid runs need cost approval, and destructive or out-of-scope changes need agreement before proceeding.
17
+
18
+ ## Choose a design that fits the task
19
+
20
+ - Start with representative inputs and the output the user needs. Reuse an existing pipeline or node when it already serves that purpose; prefer the simplest graph that meets the requirements.
21
+ - Use `code` for deterministic transformations, scripts, or programmatic API/LLM calls; `generation` for the platform's human or synthetic generation journey, including original content collection; `quorum` for independent annotations where agreement or disagreement matters; and `match` for conditional routing. `root` defines the input/output boundary.
22
+ - Choose data contracts, audience, instructions, and quality criteria together: the person doing the task should be able to produce the declared output and understand how it will be judged. Let the task and observed data guide these choices rather than copying an example's settings.
23
+ - Treat quality, turnaround, and cost as tradeoffs. Explain meaningful assumptions, and seek clarification for unresolved acceptance criteria rather than inventing business rules. Read [node semantics](references/node-semantics.md) for each selected node's actual capabilities and constraints.
17
24
 
18
25
  ## Follow the reconciliation loop
19
26
 
27
+ For an applied change, the dependencies are read → edit → check/validate → plan → apply → confirm convergence. Iterate locally as needed. For inspection, design, or check-only requests, stop at the requested deliverable rather than creating resources, applying changes, or starting a run merely to finish this sequence.
28
+
20
29
  1. Read `toloka.json` when present, then read the relevant `pipelines/**/pipeline.ts` module and everything it imports.
21
30
  2. Edit the TypeScript source. Treat it as authoritative desired state.
22
31
  3. Run the complete local gate, then validate each changed pipeline against the platform:
@@ -25,7 +34,7 @@ Do not replace the guide's quick demo with another example, and do not run the d
25
34
  toloka validate
26
35
  ```
27
36
  4. Run `toloka plan`. Read the complete diff and resolve every conflict or missing prerequisite.
28
- 5. Run `toloka apply`. Apply reruns the complete local gate and proceeds only when it passes. Apply only after the plan matches the request.
37
+ 5. Show the plan and run `toloka apply` when its changes match the requested work. Resolve removals, immutable-field conflicts, or changes outside that scope with the user first. Apply reruns the complete local gate and proceeds only when it passes.
29
38
  6. Run `toloka plan` again and require `No changes.`
30
39
 
31
40
  The CLI reads source, compares it with live state, and reconciles the platform. Edit files; never mutate a pipeline through raw HTTP, SDK client methods, or internal platform tool calls. Do not make a live edit and then reverse-engineer it into source.
@@ -37,36 +46,39 @@ Use the directory containing `toloka.json` as the source root. Commands default
37
46
  - If `toloka.json` exists, read it as CLI-managed identity state and confirm its `projectId` matches `toloka project current` before any plan or apply. It maps the project, pipeline source directories, and dataset names to live IDs. Do not hand-edit it.
38
47
  - If it is absent and the user is adopting an existing project, run `toloka project add <alias> <projectId>`, then run `toloka import <projectId>` in the intended source root before `toloka init`. Import refuses an existing `pipelines/` directory unless you pass `--force`.
39
48
  - After importing an existing project, run `toloka plan` before editing and require `No changes.`. Resolve importer or live-state drift separately so it cannot be mistaken for your change.
40
- - If it is absent and the user is authoring from scratch, run `toloka project create <alias>` before `toloka init`. Confirm `toloka project current` and the generated `toloka.json` name the new project before authoring.
49
+ - If it is absent and the user is authoring from scratch, create a project with a task-derived name when a new project is needed. For an intended existing empty project, use `toloka project add <alias> <projectId>` and `toloka --project-id <projectId> init`. Confirm `toloka project current` and the generated `toloka.json` name the intended project before authoring; do not create a duplicate merely because the checkout is unbound.
41
50
 
42
51
  If `toloka project current` reports `from toloka.json` for a project you did not select in this checkout, stop: project create/add/switch does not rebind an existing checkout. A newly generated state file with empty `pipelines` and `datasets` can be removed before selecting the intended project and rerunning `toloka init`; any state file with live bindings may be someone else's checkout and must not be deleted without user approval.
43
52
 
44
- Never assume a project ID from conversation context. Resolve it from `--project-id`, `TOLOKA_PROJECT_ID` / `POTATO_PROJECT_ID`, `toloka.json`, or `toloka project current`.
53
+ Never assume a project ID from conversation context. Resolve it from `--project-id`, `TOLOKA_PROJECT_ID`, `toloka.json`, or `toloka project current`.
45
54
 
46
- `project create`, `project add`, and `project switch` also change the machine-level current-project registry used outside a source root. For temporary or evaluation projects, record the previous alias and restore it before finishing. If create requires `--team-id`, use the team from `toloka status --project-id <authorized-project>` only when that project is known to share the intended owner; state the assumption and confirm the new project's team in `toloka project url`. With no such project, ask the user for the team ID.
55
+ An unverified trial account holds one project and one pipeline, and cannot deploy or run. `project create` then fails with `Your trial allows a single project.` and pipeline creation with `Your trial allows a single pipeline.` Adopt the project that already exists instead: register it with `toloka project add <alias> <projectId>`, bind the checkout with `toloka import <projectId>`, and author inside its existing pipeline; the platform has no project delete, so there is nothing to clear. Both limits lift when the user completes identity or business verification from the banner in the platform.
56
+
57
+ `project create`, `project add`, and `project switch` also change the machine-level current-project registry used outside a source root. For temporary or evaluation projects, record the previous alias and restore it before finishing. Without `--team-id`, create uses the account's only writable team; when `toloka whoami` lists several teams, ask the user which one owns the project and pass it explicitly. Confirm the new project's team in `toloka project url`.
47
58
 
48
59
  ## Author with the typed graph API
49
60
 
50
61
  Import authoring helpers from `@toloka-platform/sdk`.
51
62
 
52
63
  - Declare every data contract once with `field(name, jsonSchema)`.
53
- - Do not invent enum, length, range, format, label-precedence, tie-break, default, exact-phrase, or conditional-requiredness rules absent from the request or observed data. Before apply, list every authored rule the request did not fix—including criteria, quiz answers, and UI validation—as an assumption; choose the least surprising option and carry that list into the final report.
54
- - Use exactly these constructors: `root`, `code`, `generation`, `match`, and `quorum`.
64
+ - Decide entity cardinality from the task before choosing field schemas or Task UI components. One logical output from one labeler is a static entity, even when a component represents it with an array; only multiple independent outputs are dynamic. For dynamic entities, choose a tight task-grounded `maxEntities` instead of defaulting to 50.
65
+ - Ground enum, length, range, format, label-precedence, tie-break, default, exact-phrase, and conditional-requiredness rules in the request, observed data, or documented platform requirements. Derive criteria, quiz answers, and UI validation from that evidence. Surface assumptions that affect accepted outputs before apply; if materially different interpretations remain, ask instead of silently deciding the user's business rules.
66
+ - The supported node constructors are `root`, `code`, `generation`, `match`, and `quorum`.
55
67
  - Connect typed ports with `connect(from, to)`: `started`, `completed`, `input`, `output`, `matchNode.matched(0)`, and `default`.
56
68
  - Export a default `definePipeline({ dataset, fields, nodes, connections })` from every `pipelines/**/pipeline.ts`.
57
69
  - Keep the graph acyclic. Put review, retry, training, exam, appeal, and payment behavior in the owning human-work node rather than adding loop nodes.
58
70
 
59
71
  Let constructors mint IDs for new declarations. Preserve `id` options generated by `toloka import`, but never invent or hand-edit raw `fp_…`, `ds.…`, `pl.…`, or `pp.…` values in authored settings. Never add a `layout` block: layout is not authored, existing layout is preserved, and the server supplies defaults.
60
72
 
61
- Read [node semantics](references/node-semantics.md) before selecting or configuring a node. Use `node_modules/@toloka-platform/sdk/examples/face-image-collection/` as a concrete authoring pattern.
73
+ Use `node_modules/@toloka-platform/sdk/examples/face-image-collection/` as a concrete authoring pattern when relevant; borrow its structure, not its task-specific choices.
62
74
 
63
75
  ## Get human-work settings right the first time
64
76
 
65
- These are server rules that `definePipeline` does not check. Each one costs an apply or a failed deployment to discover.
77
+ Distinguish server requirements from optional design choices. The following constraints and defaults are not all checked by `definePipeline`:
66
78
 
67
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.
68
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.
69
- - **Do not author placeholder optional settings.** Omit `exam`, non-default QA, audience reuse, and smart-search blocks unless the user requested them or imported source already controls them. An empty disabled block is still authored state.
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.
70
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.
71
83
 
72
84
  ## Know the validation boundary
@@ -79,7 +91,9 @@ These are server rules that `definePipeline` does not check. Each one costs an a
79
91
 
80
92
  Before choosing Task UI components, call `ui.componentDocumentation()` from a local `@toloka-platform/sdk/testing` scenario. A component's usable contract is the returned `propsType` plus its returned `valueType` and `example`; shared `Field` props such as `path`, `label`, `hint`, and `validation` can be confirmed from any current `Field.*` example, but do not invent any other prop. For structured or array-valued Fields, derive the dataset field schema from `valueType`, then feed the documented example value through `setValue`, `getValue`, and `submit` in the UI scenario so upstream contract drift fails locally. Never translate undocumented property names or replace missing values with defaults. Every identifier in `ui.code` must be a returned component or documented `actions` API, and JSX must have one root element. Register each required UI scenario with `test.ui(pipeline, node, name, callback)` and submit through its bound `render` helper. Run `toloka check <pipeline> --node <name-or-id>` after every Task UI edit; require passing UI types, empty browser validation errors, valid postprocessed entity output, and visual inspection where relevant. Never weaken authored validation merely to make a test pass.
81
93
 
82
- Register code behavior with `test.code(pipeline, node, name, callback)` and execute the bound `run` helper. Add at least one `test.pipeline(pipeline, name, callback)` scenario. When a local dataset file is available, use its first row as the initial item state; redact sensitive values while preserving field names, nesting, optionality, and media/value shapes. Use synthetic input only when no local row exists. Treat the fixture as `root.started` item state, execute connected nodes in order with the callback's bound code and UI helpers, merge only each node's declared outputs, and assert the final `root.completed` fields. One scenario is appropriate for a linear happy path; use separate scenarios for different match branches, optional paths, and failures.
94
+ `ui.code` accepts TSX, including TypeScript annotations. `preprocess` and `postprocess` are JavaScript function bodies; do not put TypeScript-only syntax in either transform.
95
+
96
+ Register code behavior with `test.code(pipeline, node, name, callback)` and execute the bound `run` helper. Add at least one `test.pipeline(pipeline, name, callback)` scenario. Choose representative fixtures from available data, redacting sensitive values while preserving field names, nesting, optionality, and media/value shapes. Use synthetic cases when needed for privacy or to exercise boundaries absent from the sample. Treat the fixture as `root.started` item state, execute connected nodes in order with the callback's bound code and UI helpers, merge only each node's declared outputs, and assert the final `root.completed` fields. Cover meaningful match branches, optional paths, and failures as well as the happy path.
83
97
 
84
98
  ## Keep data and credentials out of source
85
99
 
@@ -89,9 +103,9 @@ Register code behavior with `test.code(pipeline, node, name, callback)` and exec
89
103
  ## Credentials
90
104
 
91
105
  `toloka login` verifies an API key and stores it with owner-only permissions, so no later command needs
92
- `--api-key`. Precedence is flag, then environment variable (`POTATO_API_KEY`, `POTATO_BASE_URL`), then
106
+ `--api-key`. Precedence is flag, then environment variable (`TOLOKA_API_KEY`, `TOLOKA_BASE_URL`), then
93
107
  that file. `toloka auth-status` reports what is in effect and where it came from; `toloka logout`
94
- removes it. If a command reports missing credentials, run `toloka login`; never invent a key.
108
+ removes it. If credentials are missing, ask the user to run `toloka login` in their terminal; never request a key in chat.
95
109
  Anonymous command telemetry is on by default; set `TOLOKA_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable it.
96
110
  A globally installed CLI auto-updates by default; turn that off with `toloka config set auto-update false`.
97
111
 
@@ -104,14 +118,14 @@ A globally installed CLI auto-updates by default; turn that off with `toloka con
104
118
 
105
119
  ## Run a deployed pipeline
106
120
 
107
- Before starting a run, require a passing `toloka check` and no blocking error from `toloka validate`. A warning-severity `not_ran_node_check` concerns a separate Remote Node Check and does not block the Local Check Gate; an error-severity instance remains a blocking remote-validation result. Run `toloka pipeline cost <name>` when pricing evidence is needed; if it skips a billed node, report the authored rate and a labeled labor floor instead of presenting `$0.00` as the price.
121
+ Before starting a run, require a passing `toloka check` and no blocking error from `toloka validate`. A warning-severity `not_ran_node_check` concerns a separate Remote Node Check and does not block the Local Check Gate; an error-severity instance remains a blocking remote-validation result. Run `toloka pipeline cost <name>` and present the forecast for user approval before starting the run. If it skips a billed node, report the authored rate and a labeled labor floor instead of presenting `$0.00` as the price; make the missing pricing evidence clear when seeking approval.
108
122
 
109
123
  Start a run with `toloka pipeline run <name> --wait --timeout <ms>`, then read its exit code: `0` succeeded, `1` reached a failed terminal state, `2` still running when the window closed. Without `--wait`, exit `0` only means the run was accepted. Nothing reports back later, so never describe a started run as a finished one. Name the live pipeline; there is no implicit only-pipeline.
110
124
 
111
- Always bound the wait. A queue with no one working it stays in progress indefinitely, so an unbounded poll loop ends with you killed and reporting nothing. On exit `2`, stop waiting and report what you observed: item counts, current states, and that the run had not finished. A bounded honest report beats an unbounded silent wait. Use `toloka pipeline status <name>` and `toloka pipeline results <runId> --failed` for counts, states, and errors. `toloka status` (no prefix) is project health, not the latest run.
125
+ Keep monitoring bounded so the user receives a useful update even when expert work or queues take time. On exit `2`, report the observed item counts and states and say the run is still in progress; choose a further bounded check only when it serves the request. Use `toloka pipeline status <name>` and `toloka pipeline results <runId> --failed` for counts, states, and errors. `toloka status` (no prefix) is project health, not the latest run.
112
126
 
113
127
  ## Report with evidence
114
128
 
115
- Deliver that report in the same reply that does the work. There is no later turn and no background poller that will speak for you: if you end by promising to report once a window closes, the observation is lost and the work counts for nothing. Poll in the foreground, then state what you saw before you finish.
129
+ Explain what changed, how it meets the task, what you verified, and what remains unresolved. Include relevant project/pipeline links, meaningful design assumptions, and observed run state and cost. Distinguish applied, validated, started, and completed; do not promise a later update unless a real reporting mechanism exists.
116
130
 
117
- For an autonomous or audited platform change, save stdout, stderr, and exit status for skill discovery and every networked mutation, check, and project-registry change outside authored source, then cite those records for counts, exit codes, and convergence claims. If skill installation fails, record the failure and identify the exact skill path and version or digest followed instead. Every reported defect or guidance gap must cite a saved record or be labeled `unrecorded`; mark recurrences from earlier work. Classify each as a skill rule, a rule present but not followed, a documentation gap, or a CLI/platform defect; use the bundled `toloka-report-issue` skill for product defects instead of teaching a workaround as normal workflow. Report every authored rule not fixed by the request as an assumption. For visual evidence, list every saved screenshot as inspected or uninspected and limit appearance claims to the inspected set.
131
+ Keep enough command output and exit-status evidence to support claims about checks, mutations, and convergence, redacting secrets and sensitive data. For an audited task, retain the requested detailed records, including skill versions and project-registry changes. State when evidence is missing, and limit visual claims to surfaces you actually inspected. Use `toloka-report-issue` for product defects rather than presenting a workaround as normal workflow.
@@ -68,7 +68,7 @@ The dataset name belongs in `definePipeline({ dataset: 'name', ... })`, not in t
68
68
 
69
69
  Use `code` whenever the result can be computed from inputs without a human task. This includes deterministic transforms, ETL, filtering, parsing, arithmetic, string manipulation, scripts, HTTP APIs, and LLM API calls. An LLM call made programmatically is still `code`; choose `generation` only when the platform's human or synthetic generation journey is wanted.
70
70
 
71
- Use a downstream `code` node after `quorum` only when the user asks for a derived consensus value such as majority vote, average, or deduplication. Quorum itself returns raw collected annotations.
71
+ Use a downstream `code` node after `quorum` when the requested deliverable needs a derived consensus value such as majority vote, average, or deduplication. Quorum itself returns raw collected annotations. Choose an aggregation rule grounded in the task, and clarify material ambiguity rather than inventing label precedence.
72
72
 
73
73
  ### Configure it
74
74
 
@@ -137,10 +137,11 @@ Use `about.projectType: 'data_collection'` when experts produce new original con
137
137
 
138
138
  #### Entities
139
139
 
140
- An authored entity references a declared `field`. Set `entityType`, `optional`, `jsonPath`, `description`, `relations`, and the discriminant:
140
+ An authored entity references a declared `field`. Choose its cardinality from the task's meaning before choosing the field schema or Task UI component:
141
141
 
142
- - `dynamic: false` means one value in one annotation; use a path without `[*]` and omit `maxEntities`.
143
- - `dynamic: true` means repeated values inside one annotation; use exactly one `[*]` in `jsonPath` and set `maxEntities` from 1 through 50.
142
+ - One logical result from one labeler is static. A caption, verdict, rating, recording, or upload remains one entity even when its value is an object or a component holds it in an array. Omit `dynamic` and `maxEntities`, and use a `jsonPath` without `[*]`.
143
+ - Multiple independent results from one labeler are dynamic. Examples include one box per visible face and one defect record per discovered defect. Set `dynamic: true`, use exactly one `[*]` in `jsonPath`, and set `maxEntities` to the tightest upper bound justified by the task. Never use 50 as an unexamined default.
144
+ - Do not choose `dynamic` from a TypeScript or JSON container shape. Ask whether the task expects one logical result or a repeated collection; the answer owns the entity model.
144
145
  - Use `allowedLabels: [{ label, value }]` for fixed choices. Use `SINGLE_LABEL` for exactly one stored value and `MULTI_LABEL` for multiple values.
145
146
  - Set media duration bounds only when the expert produces the media through an upload or recording output. Input media used for annotation does not require duration bounds.
146
147
  - Give every output entity at least one relation to the input it uses: `{ field, rel_type: 'context' | 'references' | 'depends_on' | 'evaluates' }`, or a conditional relation supported by the public type.
@@ -149,7 +150,7 @@ An authored entity references a declared `field`. Set `entityType`, `optional`,
149
150
 
150
151
  Entities enforce format, not meaning. Put types, ranges, cardinality, requiredness, and labels in the field schema and entity. Put accuracy, correctness, completeness, and clarity in quality criteria.
151
152
 
152
- For any single-item upload or recording control, the component value is still an array. Declare the output field as a top-level array with `minItems: 1` and `maxItems: 1`, the output entity as `dynamic: true` with `maxEntities: 1` and a `jsonPath` ending in `[*]`, and use the matching media or document entity type. Map the component's documented completed-value link field in `postprocess`. For video, also set both entity duration bounds and align them with the UI component.
153
+ For a single-item upload or recording control, the component value is still an array, but the task produces one logical entity. Declare a scalar output field, keep the entity static, and use a non-wildcard path to the completed first value, such as `$.video_file[0].downloadLink`. Do not model the component's array container as `dynamic: true`. Use the matching media or document entity type. For video, also set both entity duration bounds and align them with the UI component.
153
154
 
154
155
  #### Quality and instructions
155
156
 
@@ -157,17 +158,17 @@ Write at least one criterion for every output entity. Each criterion needs an au
157
158
 
158
159
  Use `llmQaInstruction` only when the evaluator needs a specific verification method, authoritative source, tool, or pinned edge case beyond the thresholds. It is evaluator guidance, not labeler guidance, and has no effect in `human_only` mode.
159
160
 
160
- Default QA is `qualityAssurance: { qaMode: 'llm_only' }`. Do not ask whether QA is wanted. Use `hybrid` only when the user explicitly requests human review; it adds sampled Human QA while retaining LLM review. Use `human_only` only when the user explicitly prohibits LLM grading. Human-bearing modes require `humanQaTimeForTask` of at least 10 seconds; omit `smartSamplingPercent` for the platform defaults of 30 for hybrid and 100 for human-only unless the user asks for another rate. QA mode applies to the whole node, not individual criteria. The redo cap is platform-controlled and is not an SDK setting.
161
+ Default QA is `qualityAssurance: { qaMode: 'llm_only' }`. Keep it when it fits the task. `hybrid` adds sampled Human QA while retaining LLM review; `human_only` is appropriate when LLM grading is prohibited or human review alone is required. Recommend a mode based on the user's quality and privacy requirements, explaining cost and turnaround implications before changing it. Human-bearing modes require `humanQaTimeForTask` of at least 10 seconds; `smartSamplingPercent` defaults to 30 for hybrid and 100 for human-only. Use those defaults unless the task justifies a different rate. QA mode applies to the whole node, not individual criteria. The redo cap is platform-controlled and is not an SDK setting.
161
162
 
162
163
  Keep `instruction` actionable and in English. Include the workflow, concepts, quality rules, and at least one pass and fail example grounded in the task. Do not mention project schedules, dataset volume, workforce requirements, or compensation in labeler instructions.
163
164
 
164
165
  #### Audience and pricing
165
166
 
166
- 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. Start unspecified filters with English, no specializations, and no countries. 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 do not invent one when the SDK cannot discover it.
167
168
 
168
- Start with `$0.20` and 120 seconds when the task gives no stronger signal, then change them only for an explicit rate or clearly longer work. The per-expert cap is normally off. For `data_collection`, use a cap of 50 by default; use 1 for one-response-per-expert collection.
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.
169
170
 
170
- Use `audienceType: 'synthetic'` only when the user explicitly asks for synthetic or model-generated data. Set the required `maxCostPerAttempt`, the per-attempt ceiling in charged US dollars across fresh input, cached input, and output together, and configure the optional `generationModelId`, `reasoningEffort`, and `llmInstruction`; do not include human pricing or audience fields. Take `generationModelId` only from the union the SDK exports, and never invent an id; when the user names no model, omit the property and accept the platform default instead of guessing one. Synthetic generation is incompatible with `data_collection`, human QA, audience reuse, expert sourcing, and Training.
171
+ Choose `audienceType: 'synthetic'` when model-generated data serves the requested outcome; preserve an explicit requirement for human judgments or original human content. Explain the quality and cost tradeoff if recommending synthetic generation. Set the required `maxCostPerAttempt`, the per-attempt ceiling in charged US dollars across fresh input, cached input, and output together, and configure the optional `generationModelId`, `reasoningEffort`, and `llmInstruction`; do not include human pricing or audience fields. Take `generationModelId` only from the union the SDK exports. Use a supported model suited to the task when there is evidence for that choice, or omit the property to use the platform default; do not guess IDs or capabilities. Synthetic generation is incompatible with `data_collection`, human QA, audience reuse, expert sourcing, and Training.
171
172
 
172
173
  #### Training, Exam, UI, and advanced settings
173
174
 
@@ -217,7 +218,7 @@ Configure entities for one labeler's contribution, not for the outer array. A si
217
218
 
218
219
  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.
219
220
 
220
- Quorum does not aggregate. It writes all raw annotations back, including rejected ones. Add a downstream `code` node only when the user asks for one consensus value, and make it tolerate arrays longer than `overlap`.
221
+ Quorum does not aggregate. It writes all raw annotations back, including rejected ones. Add a downstream `code` node when the requested deliverable needs one consensus value, and make it tolerate arrays longer than `overlap`.
221
222
 
222
223
  #### Explanation-driven quality
223
224
 
@@ -231,7 +232,7 @@ Default to `qualityAssurance: { qaMode: 'llm_only' }`. The LLM accepts or reject
231
232
 
232
233
  **Quorum has no redo cycle.** A rejected annotation is never reopened or sent back to the same expert. Escalation adds a fresh annotation, and all collected annotations—accepted and rejected—remain in the output arrays. Hitting the cap with zero accepted annotations still returns the collected results.
233
234
 
234
- Use `qaMode: 'none'` only when the user explicitly asks for agreement-based quality control instead of LLM QA. Then:
235
+ Use `qaMode: 'none'` when agreement-based quality control fits the task better than LLM grading, explaining the tradeoff before changing an existing QA strategy. This mode requires:
235
236
 
236
237
  - set `overlap` to at least 3;
237
238
  - disable the per-expert cap;
@@ -262,6 +263,7 @@ Set `MatchAuthoringSettings`, derived from `MatchNodeSettings`, through `match(n
262
263
  - `about`: `name`, optional `description`, optional `projectType`.
263
264
  - `input`: every declared `Field` referenced by a predicate, each with `optional`.
264
265
  - `conditions`: ordered branches with optional `logic: 'and' | 'or'` and required `predicates`.
266
+ - Each condition `name` is a unique identifier within its Match node, from 2 through 32 characters: start with a lowercase letter, use only lowercase letters, digits, and underscores, and end with a letter or digit. Use `is_disputed`, not `is disputed` or `field_type = general_info`. `match()` throws locally for invalid or duplicate names.
265
267
  - Each authored predicate uses `field`, `jsonPath`, `operator`, and scalar `value`.
266
268
 
267
269
  The current public type accepts only `operator: 'text_eq' | 'text_neq'` and `value: string | number | boolean | null`. Do not copy broader internal operator lists into source. Use `jsonPath: '$'` for the whole scalar or a restricted path into an object.