@toloka-platform/sdk 0.1.0-preview.4 → 0.1.0-preview.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/toloka.js +132 -126
- package/dist/cli/toloka.js.jsc +0 -0
- package/dist/cli/toloka.js.jsc.sha256 +1 -1
- package/dist/cli/toloka.js.sha256 +1 -1
- package/docs/cli-v2.md +4 -0
- package/docs/cli.md +82 -6
- package/docs/datasets.md +8 -9
- package/docs/getting-started.md +2 -2
- package/docs/limitations.md +5 -8
- package/docs/troubleshooting.md +0 -11
- package/openapi/gen/api.ts +782 -876
- package/openapi/gen/models/baseModel.ts +9 -0
- package/openapi/gen/models/baseModelId.ts +2 -0
- package/openapi/gen/models/baseModelIdProperty.ts +2 -0
- package/openapi/gen/models/createDatasetBody.ts +2 -0
- package/openapi/gen/models/createDatasetBodyProfile.ts +2 -0
- package/openapi/gen/models/createDatasetUploadBodyFormat.ts +1 -1
- package/openapi/gen/models/createProjectModelBody.ts +8 -0
- package/openapi/gen/models/createProjectModelBodyDescription.ts +2 -0
- package/openapi/gen/models/dataset.ts +2 -0
- package/openapi/gen/models/datasetProfile.ts +3 -0
- package/openapi/gen/models/datasetProfileStamp.ts +6 -0
- package/openapi/gen/models/datasetProfileStampName.ts +2 -0
- package/openapi/gen/models/generationNodeSettingsAudienceAndPricingOneOfOneone.ts +1 -0
- package/openapi/gen/models/index.ts +21 -0
- package/openapi/gen/models/listBaseModels200.ts +5 -0
- package/openapi/gen/models/listModelVersions200.ts +7 -0
- package/openapi/gen/models/listModelVersionsParams.ts +5 -0
- package/openapi/gen/models/listProjectModels200.ts +7 -0
- package/openapi/gen/models/listProjectModelsParams.ts +5 -0
- package/openapi/gen/models/model.ts +16 -0
- package/openapi/gen/models/modelArchivedAt.ts +2 -0
- package/openapi/gen/models/modelDescription.ts +2 -0
- package/openapi/gen/models/modelId.ts +2 -0
- package/openapi/gen/models/modelVersion.ts +9 -0
- package/openapi/gen/models/modelVersionId.ts +2 -0
- package/openapi/gen/models/pipelineGraphSnapshotGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneone.ts +1 -0
- package/openapi/gen/models/runCost.ts +7 -0
- package/openapi/gen/models/validatePipelineGraphBodyGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneone.ts +1 -0
- package/package.json +2 -1
- package/skills/catalog.json +22 -0
- package/skills/{SKILL.md → toloka-build/SKILL.md} +2 -2
- package/skills/{references → toloka-build/references}/workflow-and-cli.md +26 -5
- package/skills/toloka-report-issue/SKILL.md +25 -0
- package/skills/toloka-report-issue/references/report-template.md +34 -0
- package/src/cli/analytics.ts +53 -1
- package/src/cli/data.ts +148 -25
- package/src/cli/file-system.ts +34 -0
- package/src/cli/format-error.ts +19 -0
- package/src/cli/init.ts +149 -194
- package/src/cli/models.ts +188 -0
- package/src/cli/program.ts +202 -22
- package/src/cli/report.ts +144 -0
- package/src/cli/skill.ts +363 -0
- package/src/client.ts +109 -35
- package/src/errors.ts +25 -10
- package/src/pipeline-graph-v1.contract.json +5 -1
- package/src/transport.ts +16 -13
- /package/skills/{references → toloka-build/references}/node-semantics.md +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
|
|
2
|
-
export type CreateDatasetUploadBodyFormat = 'json' | 'csv';
|
|
2
|
+
export type CreateDatasetUploadBodyFormat = 'json' | 'csv' | 'jsonl';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { CreateProjectModelBodyDescription } from './createProjectModelBodyDescription';
|
|
2
|
+
import type { BaseModelId } from './baseModelId';
|
|
3
|
+
|
|
4
|
+
export type CreateProjectModelBody = {
|
|
5
|
+
name: string;
|
|
6
|
+
description?: CreateProjectModelBodyDescription;
|
|
7
|
+
baseModelId: BaseModelId;
|
|
8
|
+
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { DatasetId } from './datasetId';
|
|
2
2
|
import type { ProjectId } from './projectId';
|
|
3
|
+
import type { DatasetProfile } from './datasetProfile';
|
|
3
4
|
|
|
4
5
|
export interface Dataset {
|
|
5
6
|
id: DatasetId;
|
|
6
7
|
projectId: ProjectId;
|
|
7
8
|
name: string;
|
|
8
9
|
hidden: boolean;
|
|
10
|
+
profile: DatasetProfile;
|
|
9
11
|
createdAt: string;
|
|
10
12
|
}
|
|
@@ -6,4 +6,5 @@ export type GenerationNodeSettingsAudienceAndPricingOneOfOneone = {
|
|
|
6
6
|
generationModelId?: GenerationNodeSettingsAudienceAndPricingOneOfOneoneGenerationModelId;
|
|
7
7
|
reasoningEffort?: GenerationNodeSettingsAudienceAndPricingOneOfOneoneReasoningEffort;
|
|
8
8
|
llmInstruction?: string;
|
|
9
|
+
maxCostPerAttempt: number;
|
|
9
10
|
};
|
|
@@ -19,6 +19,9 @@ export * from './attachPipelineDatasetBodyItemFilterFieldValuesItemSourcesItem';
|
|
|
19
19
|
export * from './attachPipelineDatasetBodyItemFilterFieldValuesItemSourcesItemOneOf';
|
|
20
20
|
export * from './attachPipelineDatasetBodyItemFilterFieldValuesItemSourcesItemOneOfTwo';
|
|
21
21
|
export * from './attachPipelineDatasetBodyItemFilterFieldValuesItemValue';
|
|
22
|
+
export * from './baseModel';
|
|
23
|
+
export * from './baseModelId';
|
|
24
|
+
export * from './baseModelIdProperty';
|
|
22
25
|
export * from './checkJob';
|
|
23
26
|
export * from './checkJobError';
|
|
24
27
|
export * from './checkJobResult';
|
|
@@ -68,6 +71,7 @@ export * from './codeNodeSettingsFieldProxiesInputItem';
|
|
|
68
71
|
export * from './codeNodeSettingsFieldProxiesOutputItem';
|
|
69
72
|
export * from './copyPipelineBody';
|
|
70
73
|
export * from './createDatasetBody';
|
|
74
|
+
export * from './createDatasetBodyProfile';
|
|
71
75
|
export * from './createDatasetExportBody';
|
|
72
76
|
export * from './createDatasetField200';
|
|
73
77
|
export * from './createDatasetFieldBody';
|
|
@@ -95,6 +99,8 @@ export * from './createProjectBody';
|
|
|
95
99
|
export * from './createProjectBodyDeliveryOrderId';
|
|
96
100
|
export * from './createProjectFileUpload200';
|
|
97
101
|
export * from './createProjectFileUploadBody';
|
|
102
|
+
export * from './createProjectModelBody';
|
|
103
|
+
export * from './createProjectModelBodyDescription';
|
|
98
104
|
export * from './createdDatasetFields';
|
|
99
105
|
export * from './currentUser';
|
|
100
106
|
export * from './currentUserEmail';
|
|
@@ -111,6 +117,9 @@ export * from './datasetItem';
|
|
|
111
117
|
export * from './datasetItemCurrentSubmissionId';
|
|
112
118
|
export * from './datasetItemDuplicateOfSubmissionId';
|
|
113
119
|
export * from './datasetItemId';
|
|
120
|
+
export * from './datasetProfile';
|
|
121
|
+
export * from './datasetProfileStamp';
|
|
122
|
+
export * from './datasetProfileStampName';
|
|
114
123
|
export * from './estimatePipelineCostBody';
|
|
115
124
|
export * from './estimatePipelineCostBodyItemFilter';
|
|
116
125
|
export * from './estimatePipelineCostBodyItemFilterFieldSourcesItem';
|
|
@@ -245,10 +254,13 @@ export * from './jsonSchema';
|
|
|
245
254
|
export * from './jsonSchemaAdditionalProperties';
|
|
246
255
|
export * from './jsonSchemaType';
|
|
247
256
|
export * from './jsonSchemaTypeAnyOfItem';
|
|
257
|
+
export * from './listBaseModels200';
|
|
248
258
|
export * from './listDatasetFields200';
|
|
249
259
|
export * from './listDatasetFieldsParams';
|
|
250
260
|
export * from './listDatasetItems200';
|
|
251
261
|
export * from './listDatasetItemsParams';
|
|
262
|
+
export * from './listModelVersions200';
|
|
263
|
+
export * from './listModelVersionsParams';
|
|
252
264
|
export * from './listPipelineChecks200';
|
|
253
265
|
export * from './listPipelineRunItems200';
|
|
254
266
|
export * from './listPipelineRunItemsParams';
|
|
@@ -257,6 +269,8 @@ export * from './listPipelineRunsParams';
|
|
|
257
269
|
export * from './listProjectDatasets200';
|
|
258
270
|
export * from './listProjectDatasetsParams';
|
|
259
271
|
export * from './listProjectFiles200';
|
|
272
|
+
export * from './listProjectModels200';
|
|
273
|
+
export * from './listProjectModelsParams';
|
|
260
274
|
export * from './listProjectPipelines200';
|
|
261
275
|
export * from './listProjectPipelinesParams';
|
|
262
276
|
export * from './listProjectSecrets200';
|
|
@@ -273,6 +287,12 @@ export * from './matchNodeSettingsConditionsItemPredicatesItemOperator';
|
|
|
273
287
|
export * from './matchNodeSettingsConditionsItemPredicatesItemValue';
|
|
274
288
|
export * from './matchNodeSettingsFieldProxies';
|
|
275
289
|
export * from './matchNodeSettingsFieldProxiesInputItem';
|
|
290
|
+
export * from './model';
|
|
291
|
+
export * from './modelArchivedAt';
|
|
292
|
+
export * from './modelDescription';
|
|
293
|
+
export * from './modelId';
|
|
294
|
+
export * from './modelVersion';
|
|
295
|
+
export * from './modelVersionId';
|
|
276
296
|
export * from './pagination';
|
|
277
297
|
export * from './patchPipelineNodeBody';
|
|
278
298
|
export * from './patchPipelineNodeBodySettings';
|
|
@@ -691,6 +711,7 @@ export * from './rootNodeSettingsItemFilterFieldValuesItemSourcesItemOneOfTwo';
|
|
|
691
711
|
export * from './rootNodeSettingsItemFilterFieldValuesItemValue';
|
|
692
712
|
export * from './rootNodeSettingsStartedFieldProxies';
|
|
693
713
|
export * from './rootNodeSettingsStartedFieldProxiesOutputItem';
|
|
714
|
+
export * from './runCost';
|
|
694
715
|
export * from './runId';
|
|
695
716
|
export * from './runItem';
|
|
696
717
|
export * from './runItemId';
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ModelId } from './modelId';
|
|
2
|
+
import type { ProjectId } from './projectId';
|
|
3
|
+
import type { ModelDescription } from './modelDescription';
|
|
4
|
+
import type { BaseModelId } from './baseModelId';
|
|
5
|
+
import type { ModelArchivedAt } from './modelArchivedAt';
|
|
6
|
+
|
|
7
|
+
export interface Model {
|
|
8
|
+
id: ModelId;
|
|
9
|
+
projectId: ProjectId;
|
|
10
|
+
name: string;
|
|
11
|
+
description: ModelDescription;
|
|
12
|
+
baseModelId: BaseModelId;
|
|
13
|
+
archivedAt: ModelArchivedAt;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
updatedAt: string;
|
|
16
|
+
}
|
|
@@ -6,4 +6,5 @@ export type PipelineGraphSnapshotGraphNodesItemOneOfThreeoneSettingsAudienceAndP
|
|
|
6
6
|
generationModelId?: PipelineGraphSnapshotGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneoneGenerationModelId;
|
|
7
7
|
reasoningEffort?: PipelineGraphSnapshotGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneoneReasoningEffort;
|
|
8
8
|
llmInstruction?: string;
|
|
9
|
+
maxCostPerAttempt: number;
|
|
9
10
|
};
|
|
@@ -6,4 +6,5 @@ export type ValidatePipelineGraphBodyGraphNodesItemOneOfThreeoneSettingsAudience
|
|
|
6
6
|
generationModelId?: ValidatePipelineGraphBodyGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneoneGenerationModelId;
|
|
7
7
|
reasoningEffort?: ValidatePipelineGraphBodyGraphNodesItemOneOfThreeoneSettingsAudienceAndPricingOneOfOneoneReasoningEffort;
|
|
8
8
|
llmInstruction?: string;
|
|
9
|
+
maxCostPerAttempt: number;
|
|
9
10
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toloka-platform/sdk",
|
|
3
|
-
"version": "0.1.0-preview.
|
|
3
|
+
"version": "0.1.0-preview.6",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Preview. Build, inspect, and operate Toloka pipeline projects as TypeScript source. The public API may change.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"build": "bun ./scripts/build-cli.ts ./dist/cli",
|
|
33
33
|
"generate": "orval --config ./openapi/orval.config.js",
|
|
34
34
|
"prepack": "bun run build",
|
|
35
|
+
"sync-skill-catalog": "bun ./scripts/sync-skill-catalog.ts",
|
|
35
36
|
"test": "vitest run",
|
|
36
37
|
"typecheck": "tsc --noEmit"
|
|
37
38
|
},
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skills": [
|
|
3
|
+
{
|
|
4
|
+
"id": "toloka-build",
|
|
5
|
+
"name": "Build Toloka pipelines as code",
|
|
6
|
+
"description": "Build, inspect, and change Toloka platform pipeline projects as TypeScript source with @toloka-platform/sdk and toloka. Use when the user wants to create, adopt, inspect, plan, or apply a pipeline project as code.",
|
|
7
|
+
"tags": ["pipelines", "authoring", "sdk"],
|
|
8
|
+
"version": "0.1.0-preview.6",
|
|
9
|
+
"digest": "d45d1124d27e19ee43c260ddf0c259ccdc343c5d641c2aeb538d6fedaeb99183",
|
|
10
|
+
"files": ["SKILL.md", "references/node-semantics.md", "references/workflow-and-cli.md"]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"id": "toloka-report-issue",
|
|
14
|
+
"name": "Report a Toloka problem",
|
|
15
|
+
"description": "Report a problem with the Toloka platform, CLI, or SDK as a redacted Markdown issue report sent through the toloka CLI only after explicit approval. Use when the user hits unexpected behavior, an error, or a bug and wants Toloka engineers to investigate.",
|
|
16
|
+
"tags": ["support", "issue", "bug", "report"],
|
|
17
|
+
"version": "0.1.0-preview.6",
|
|
18
|
+
"digest": "b71d06333786826edd51b909dfe8a20633870f235d03df4aae83d20c26e99205",
|
|
19
|
+
"files": ["SKILL.md", "references/report-template.md"]
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -46,7 +46,7 @@ Import authoring helpers from `@toloka-platform/sdk`.
|
|
|
46
46
|
|
|
47
47
|
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.
|
|
48
48
|
|
|
49
|
-
Read [node semantics](references/node-semantics.md) before selecting or configuring a node. Use
|
|
49
|
+
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.
|
|
50
50
|
|
|
51
51
|
## Get human-work settings right the first time
|
|
52
52
|
|
|
@@ -66,7 +66,7 @@ A successful `toloka validate` is necessary, not proof the pipeline can be launc
|
|
|
66
66
|
|
|
67
67
|
## Keep data and credentials out of source
|
|
68
68
|
|
|
69
|
-
- Never put dataset items in pipeline source or `toloka.json`. After apply has created or resolved the dataset, upload
|
|
69
|
+
- Never put dataset items in pipeline source or `toloka.json`. After apply has created or resolved the dataset, upload `.json`, `.jsonl`, or `.csv` rows with `toloka dataset upload <dataset> <file>`. If a later upload fails as schema-incompatible, run `toloka dataset fields <dataset>` and copy the printed `field()` declarations into source.
|
|
70
70
|
- Put secret references in node settings, but never secret values. Set values through stdin with `toloka secret set <name>`, or use `toloka secret set <name> --from-env <variable>`.
|
|
71
71
|
|
|
72
72
|
## Credentials
|
|
@@ -33,9 +33,9 @@ bun add --dev @toloka-platform/sdk
|
|
|
33
33
|
toloka init
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
`init` does not require a selected project. It checks that `@toloka-platform/sdk` is declared in `dependencies` or `devDependencies`, then writes a Claude skill
|
|
36
|
+
`init` does not require a selected project. It checks that `@toloka-platform/sdk` is declared in `dependencies` or `devDependencies`, then maintains one `<toloka>` Agent Bootstrap block in `AGENTS.md` and writes minimal pointers to it: a Claude skill at `.claude/skills/toloka-bootstrap/SKILL.md` when `.claude/` exists (or when no agent configuration exists at all) and an always-applied Cursor rule at `.cursor/rules/toloka-bootstrap.mdc` when `.cursor/rules/` exists. If a project is already selected through `--project-id`, `TOLOKA_PROJECT_ID` / `POTATO_PROJECT_ID`, `toloka.json`, or the machine registry, it also writes `toloka.json` when missing.
|
|
37
37
|
|
|
38
|
-
The
|
|
38
|
+
The bootstrap is small: it tells an agent to run `toloka --help`, search the bundled Skill Catalog with `toloka skill search <query>`, install the match with `toloka skill install <skill-id>`, and read `.agents/skills/<skill-id>/SKILL.md`. This skill is that installed copy. Commands warn on stderr when a generated legacy entry point is still present or the recorded bootstrap version differs from the installed SDK. Help, `init`, `report`, `project url`, and version invocations skip this checkout-dependent warning. The warning never blocks a command; re-run `toloka init` to refresh the bootstrap and its pointers.
|
|
39
39
|
|
|
40
40
|
## Store credentials once
|
|
41
41
|
|
|
@@ -71,13 +71,16 @@ require `toloka login` first because they read and write the credentials file. W
|
|
|
71
71
|
project ID in this order: `--project-id`, `TOLOKA_PROJECT_ID`, `POTATO_PROJECT_ID`, `toloka.json`,
|
|
72
72
|
then the machine registry `current`.
|
|
73
73
|
|
|
74
|
-
Anonymous command telemetry is on by default (`sdk_cli_command_completed` / `sdk_cli_command_failed`). Set `TOLOKA_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable
|
|
74
|
+
Anonymous command telemetry is on by default (`sdk_cli_command_completed` / `sdk_cli_command_failed`). `toloka report` uses the same PostHog client to send explicitly approved Markdown in `sdk_cli_issue_report_submitted`. Set `TOLOKA_TELEMETRY=0` or `DO_NOT_TRACK=1` to disable both; CI is off unless `TOLOKA_TELEMETRY=1`.
|
|
75
75
|
|
|
76
76
|
All commands accept `--source-root <directory>`. Prefer running from the source root so paths and diffs stay obvious. `init` does not walk up: it binds the working directory or `--source-root` only.
|
|
77
77
|
|
|
78
78
|
The real command surface is:
|
|
79
79
|
|
|
80
80
|
```text
|
|
81
|
+
toloka version
|
|
82
|
+
toloka -v
|
|
83
|
+
toloka --version
|
|
81
84
|
toloka login
|
|
82
85
|
toloka logout
|
|
83
86
|
toloka auth-status
|
|
@@ -85,6 +88,7 @@ toloka project list
|
|
|
85
88
|
toloka project add [alias] [projectId]
|
|
86
89
|
toloka project switch <alias>
|
|
87
90
|
toloka project current
|
|
91
|
+
toloka project url
|
|
88
92
|
toloka project remove <alias>
|
|
89
93
|
toloka project create [alias] [--name <name>] [--team-id <id>]
|
|
90
94
|
toloka init
|
|
@@ -105,12 +109,29 @@ toloka pipeline runs [name] [--limit <n>]
|
|
|
105
109
|
toloka pipeline cost [name] [--item-limit <n>]
|
|
106
110
|
toloka pipeline results <runId> [--limit <n>] [--failed]
|
|
107
111
|
toloka pipeline cancel <runId>
|
|
112
|
+
toloka base-model list [--json]
|
|
113
|
+
toloka base-model get <id> [--json]
|
|
114
|
+
toloka model list [--json]
|
|
115
|
+
toloka model get <name-or-id> [--json]
|
|
116
|
+
toloka model versions <name-or-id> [--json]
|
|
117
|
+
toloka model create <name> --base <base-model-id> [--description <text>] [--json]
|
|
118
|
+
toloka model archive <name-or-id> [--json]
|
|
119
|
+
toloka skill list [--json]
|
|
120
|
+
toloka skill search <query> [--json]
|
|
121
|
+
toloka skill install <skill-id> [--force]
|
|
122
|
+
toloka report <markdown> [--authored-by human|agent] [--confirm]
|
|
108
123
|
```
|
|
109
124
|
|
|
110
125
|
Select the platform project with `toloka project add` or `toloka project create` before `import`, `plan`, or `apply`. `init` may run first, and `import` uses the selected project when the id is omitted.
|
|
111
126
|
|
|
127
|
+
`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.
|
|
128
|
+
|
|
112
129
|
`toloka pipeline cost [name] [--item-limit <n>]` forecasts what a run of a live pipeline would bill. It does not start a run and does not change the graph. Name the live pipeline or id; a TTY may pick among several. The typed client equivalent is `client.pipelines.estimateCost({ pipelineId, itemLimit? })`.
|
|
113
130
|
|
|
131
|
+
## Manage model checkpoints
|
|
132
|
+
|
|
133
|
+
The global Base Model Catalog is read-only and uses `toloka base-model`. `base-model list` prints aligned ID, name, provider, and upstream-model columns by default. `toloka model` manages project-owned lineages; creation requires one catalog `baseModelId` and creates metadata without a Model Version. Every Base Model and Model command accepts `--json` for machine-readable output. Model Version upload, validation, and download commands are deferred until the separate upload-processing contract is implemented.
|
|
134
|
+
|
|
114
135
|
## Adopt an existing live project
|
|
115
136
|
|
|
116
137
|
1. Run `toloka init` in the intended source root if the agent entry points are not installed yet.
|
|
@@ -176,7 +197,7 @@ Declare the fields in source, then upload rows:
|
|
|
176
197
|
toloka dataset upload <dataset> <file>
|
|
177
198
|
```
|
|
178
199
|
|
|
179
|
-
The input
|
|
200
|
+
The CLI infers the input format from its extension and uploads the original bytes without conversion: `.json` is an array of row objects, `.jsonl` has one object per non-empty line, and `.csv` uses its header row as field names with every value ingested as a string. JSONL is validated locally before upload. If transfer or finalization fails, the CLI cancels the started upload before returning the error, so another upload can start immediately and may reuse the same filename. The dataset does not have to exist yet: when a pipeline in source binds it, upload creates it and declares that pipeline's columns, so rows land in real columns rather than in the raw `uploaded` blob. Upload refuses when no pipeline in source declares a name because it would have no column names to map onto. An id-shaped argument is never created; upload fails when that dataset id does not exist in the project. Upload appends items; applying source never deletes them.
|
|
180
201
|
|
|
181
202
|
If a later upload fails with a schema-incompatibility error, inspect the inferred schema from the first successful upload:
|
|
182
203
|
|
|
@@ -254,4 +275,4 @@ Read the returned path and reason. Check connection endpoints, duplicate or unkn
|
|
|
254
275
|
|
|
255
276
|
## Use the shipped example
|
|
256
277
|
|
|
257
|
-
Read
|
|
278
|
+
Read `node_modules/@toloka-platform/sdk/examples/face-image-collection/pipeline.ts`, its `fields.ts`, and its `nodes/` modules for a real composition of `field`, `root`, `generation`, `code`, `connect`, and `definePipeline`. Copy its source organization, not its task-specific settings.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: toloka-report-issue
|
|
3
|
+
description: Report a problem with the Toloka platform, CLI, or SDK as a redacted Markdown issue report sent through the toloka CLI only after explicit approval. Use when the user hits unexpected behavior, an error, or a bug and wants Toloka engineers to investigate.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Report a Toloka problem
|
|
7
|
+
|
|
8
|
+
Use this skill when Toloka platform, CLI, or SDK behavior blocks the user's work and they want Toloka engineers to investigate. The result is one Markdown issue report sent through the `toloka` CLI. Nothing leaves the machine until the user has reviewed the complete report and approved it.
|
|
9
|
+
|
|
10
|
+
## Workflow
|
|
11
|
+
|
|
12
|
+
1. Collect verified facts: what the user ran, what they expected, what happened, and any relevant project, pipeline, dataset, run, thread, or request IDs. Ask for missing reproduction steps or reproduce the failure with real commands. Never invent a timeline, command output, or identifier.
|
|
13
|
+
2. Copy [the template](references/report-template.md), preserve its section order, and replace the example with the user's evidence. Write `None` for sections that do not apply. The final UTF-8 Markdown file must not exceed 256 KiB.
|
|
14
|
+
3. Redact before previewing. Include only evidence the user selected. Replace every API key, token, password, cookie, connection string, or personal value with a marker such as `[REDACTED:api-key]`, and list each replacement under Redactions without the original value. Never read environment variables, credential files, shell history, or logs the user did not name.
|
|
15
|
+
4. Show the user the exact complete Markdown file and ask whether to send it. If they decline or request changes, do not submit; revise the file and ask again.
|
|
16
|
+
5. Only after approval, run `toloka report <report.md> --authored-by agent --confirm`. The command previews the same Markdown, submits it as one PostHog event, flushes delivery, and prints `Submitted issue report: <id>` only after PostHog accepts the flush.
|
|
17
|
+
6. Return the printed report ID to the user. If submission fails, keep the Markdown file, report the exact error, and do not claim success or retry without approval.
|
|
18
|
+
|
|
19
|
+
## Boundaries
|
|
20
|
+
|
|
21
|
+
- Submit only the Markdown file. The command has no attachment or structured-reference flags; put relevant IDs and text evidence in the report itself.
|
|
22
|
+
- The event contains the complete Markdown, report ID, UTF-8 byte length, declared authorship, platform origin, and the standard pseudonymous CLI telemetry context. It never reads or sends the API key.
|
|
23
|
+
- `--authored-by agent` records who prepared the report. It does not authenticate or grant access.
|
|
24
|
+
- Issue reporting is unavailable when CLI telemetry is disabled. Do not bypass that setting.
|
|
25
|
+
- Use the CLI, not the SDK or raw PostHog API. The user-visible preview and explicit approval are the consent boundary.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Issue Report: `toloka apply` returns HTTP 500 for the cat labeling project
|
|
2
|
+
|
|
3
|
+
## Summary
|
|
4
|
+
|
|
5
|
+
`toloka apply` fails with HTTP 500 after `toloka validate` passed, so the edited pipeline never reaches the platform.
|
|
6
|
+
|
|
7
|
+
## Steps to reproduce
|
|
8
|
+
|
|
9
|
+
1. Change the labeler instruction in `pipelines/cat-labeling/nodes/annotate-cats/node.ts`.
|
|
10
|
+
2. Run `toloka validate`; it reports no issues.
|
|
11
|
+
3. Run `toloka apply`.
|
|
12
|
+
|
|
13
|
+
## Expected behavior
|
|
14
|
+
|
|
15
|
+
`toloka apply` writes the new graph version and prints the changed node.
|
|
16
|
+
|
|
17
|
+
## Actual behavior
|
|
18
|
+
|
|
19
|
+
The CLI exits 1 with `Potato API request failed with status 500`. The same command failed three times between 09:12 and 09:20 UTC; `toloka plan` still shows the pending change.
|
|
20
|
+
|
|
21
|
+
## Relevant IDs
|
|
22
|
+
|
|
23
|
+
- Project: pp.0192f3a4-5b6c-7d8e-9f01-23456789abcd
|
|
24
|
+
- Pipeline: pl.0192f3a4-5b6c-7d8e-9f01-23456789abce
|
|
25
|
+
- Request: None supplied
|
|
26
|
+
|
|
27
|
+
## Environment
|
|
28
|
+
|
|
29
|
+
- toloka CLI 0.1.0-preview.6 (`toloka --version`), Bun 1.4.0, macOS 15
|
|
30
|
+
- Platform: https://platform.toloka.ai
|
|
31
|
+
|
|
32
|
+
## Redactions
|
|
33
|
+
|
|
34
|
+
- The API key in the user-selected command output was replaced with `[REDACTED:api-key]`.
|
package/src/cli/analytics.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { assert } from "es-toolkit";
|
|
1
2
|
import { randomUUID } from "node:crypto";
|
|
2
3
|
import { chmod, readFile, writeFile } from "node:fs/promises";
|
|
3
4
|
import { dirname, join } from "node:path";
|
|
@@ -28,13 +29,22 @@ export type CliAnalyticsCapture = {
|
|
|
28
29
|
readonly error?: unknown;
|
|
29
30
|
};
|
|
30
31
|
|
|
32
|
+
export type IssueReportSubmission = {
|
|
33
|
+
readonly reportId: string;
|
|
34
|
+
readonly reportText: string;
|
|
35
|
+
readonly authoredBy: "human" | "agent";
|
|
36
|
+
readonly platform: string;
|
|
37
|
+
};
|
|
38
|
+
|
|
31
39
|
export type CliAnalytics = {
|
|
32
40
|
readonly shouldIdentify: boolean;
|
|
41
|
+
readonly issueReportingEnabled: boolean;
|
|
33
42
|
readonly identifyCurrentUser: (user: {
|
|
34
43
|
readonly id: string;
|
|
35
44
|
readonly email: string | null;
|
|
36
45
|
}) => void;
|
|
37
46
|
readonly captureCommand: (event: CliAnalyticsCapture) => void;
|
|
47
|
+
readonly submitIssueReport: (report: IssueReportSubmission) => Promise<void>;
|
|
38
48
|
readonly shutdown: () => Promise<void>;
|
|
39
49
|
};
|
|
40
50
|
|
|
@@ -46,6 +56,8 @@ export type PosthogLike = {
|
|
|
46
56
|
disableGeoip: boolean;
|
|
47
57
|
}) => void;
|
|
48
58
|
alias: (event: { distinctId: string; alias: string }) => void;
|
|
59
|
+
flush: () => Promise<void>;
|
|
60
|
+
on?: (event: "error", listener: (error: Error) => void) => void;
|
|
49
61
|
shutdown: (shutdownTimeoutMs?: number) => Promise<void>;
|
|
50
62
|
};
|
|
51
63
|
|
|
@@ -86,6 +98,7 @@ const COMMAND_GROUPS: Readonly<Record<string, Readonly<Record<string, true>>>> =
|
|
|
86
98
|
},
|
|
87
99
|
dataset: { list: true, fields: true, load: true, upload: true },
|
|
88
100
|
secret: { set: true },
|
|
101
|
+
skill: { list: true, search: true, install: true },
|
|
89
102
|
};
|
|
90
103
|
|
|
91
104
|
const ROOT_COMMANDS: Readonly<Record<string, true>> = {
|
|
@@ -99,6 +112,8 @@ const ROOT_COMMANDS: Readonly<Record<string, true>> = {
|
|
|
99
112
|
plan: true,
|
|
100
113
|
status: true,
|
|
101
114
|
validate: true,
|
|
115
|
+
report: true,
|
|
116
|
+
version: true,
|
|
102
117
|
whoami: true,
|
|
103
118
|
};
|
|
104
119
|
|
|
@@ -116,6 +131,7 @@ const nameFromTokens = (tokens: readonly string[]): string => {
|
|
|
116
131
|
};
|
|
117
132
|
|
|
118
133
|
export function commandNameFromArgv(argv: readonly string[]): string {
|
|
134
|
+
if (argv.includes("-v") || argv.includes("--version")) return "version";
|
|
119
135
|
const tokens: string[] = [];
|
|
120
136
|
for (let index = 0; index < argv.length; index += 1) {
|
|
121
137
|
const token = argv[index];
|
|
@@ -161,8 +177,12 @@ const readAnonymousId = async (environment: CliEnvironment): Promise<string> =>
|
|
|
161
177
|
|
|
162
178
|
const noopAnalytics = (): CliAnalytics => ({
|
|
163
179
|
shouldIdentify: false,
|
|
180
|
+
issueReportingEnabled: false,
|
|
164
181
|
identifyCurrentUser() {},
|
|
165
182
|
captureCommand() {},
|
|
183
|
+
async submitIssueReport() {
|
|
184
|
+
assert(false, "Issue reporting is disabled. Re-run with TOLOKA_TELEMETRY=1.");
|
|
185
|
+
},
|
|
166
186
|
async shutdown() {},
|
|
167
187
|
});
|
|
168
188
|
|
|
@@ -177,6 +197,11 @@ export function createCliAnalytics(options: {
|
|
|
177
197
|
let client = options.client;
|
|
178
198
|
let distinctId = options.distinctId;
|
|
179
199
|
let identifiedUserId: string | undefined;
|
|
200
|
+
const deliveryErrors: Error[] = [];
|
|
201
|
+
const captureDeliveryError = (error: Error) => {
|
|
202
|
+
deliveryErrors.push(error);
|
|
203
|
+
};
|
|
204
|
+
client?.on?.("error", captureDeliveryError);
|
|
180
205
|
|
|
181
206
|
const ensure = async () => {
|
|
182
207
|
if (client !== undefined && distinctId !== undefined) return;
|
|
@@ -186,7 +211,7 @@ export function createCliAnalytics(options: {
|
|
|
186
211
|
flushAt: 1,
|
|
187
212
|
flushInterval: 0,
|
|
188
213
|
});
|
|
189
|
-
created.on("error",
|
|
214
|
+
created.on("error", captureDeliveryError);
|
|
190
215
|
client = created;
|
|
191
216
|
}
|
|
192
217
|
distinctId ??= await readAnonymousId(environment);
|
|
@@ -202,6 +227,7 @@ export function createCliAnalytics(options: {
|
|
|
202
227
|
let queue: Promise<void> = ensure().catch(() => {});
|
|
203
228
|
|
|
204
229
|
return {
|
|
230
|
+
issueReportingEnabled: true,
|
|
205
231
|
shouldIdentify: true,
|
|
206
232
|
identifyCurrentUser(user) {
|
|
207
233
|
queue = queue
|
|
@@ -252,6 +278,32 @@ export function createCliAnalytics(options: {
|
|
|
252
278
|
})
|
|
253
279
|
.catch(() => {});
|
|
254
280
|
},
|
|
281
|
+
submitIssueReport(report) {
|
|
282
|
+
const submission = queue.then(async () => {
|
|
283
|
+
assert(client && distinctId, "PostHog issue reporting could not be initialized.");
|
|
284
|
+
deliveryErrors.length = 0;
|
|
285
|
+
client.capture({
|
|
286
|
+
distinctId,
|
|
287
|
+
event: "sdk_cli_issue_report_submitted",
|
|
288
|
+
disableGeoip: true,
|
|
289
|
+
properties: {
|
|
290
|
+
...sharedProperties(),
|
|
291
|
+
report_id: report.reportId,
|
|
292
|
+
report_text: report.reportText,
|
|
293
|
+
report_length_bytes: new TextEncoder().encode(report.reportText).length,
|
|
294
|
+
authored_by: report.authoredBy,
|
|
295
|
+
platform: report.platform,
|
|
296
|
+
$process_person_profile: false,
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
await client.flush();
|
|
300
|
+
const reportError = deliveryErrors[0];
|
|
301
|
+
deliveryErrors.length = 0;
|
|
302
|
+
if (reportError !== undefined) throw reportError;
|
|
303
|
+
});
|
|
304
|
+
queue = submission.catch(() => {});
|
|
305
|
+
return submission;
|
|
306
|
+
},
|
|
255
307
|
async shutdown() {
|
|
256
308
|
try {
|
|
257
309
|
await queue;
|