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

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 (79) hide show
  1. package/README.md +10 -4
  2. package/dist/cli/toloka.js +159 -151
  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 +4 -3
  8. package/docs/cli.md +29 -10
  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/checkReport.ts +2 -1
  16. package/openapi/gen/models/checkReportAnyOfTwoseven.ts +5 -0
  17. package/openapi/gen/models/checkReportAnyOfTwosevenResultsItem.ts +6 -0
  18. package/openapi/gen/models/checkReportAnyOfTwosevenResultsItemVerdict.ts +2 -0
  19. package/openapi/gen/models/currentUser.ts +1 -0
  20. package/openapi/gen/models/deliveryOrder.ts +9 -0
  21. package/openapi/gen/models/deliveryOrderClientName.ts +2 -0
  22. package/openapi/gen/models/getTrainingRunMetricHistoryParams.ts +4 -0
  23. package/openapi/gen/models/index.ts +19 -0
  24. package/openapi/gen/models/listDeliveryOrders200.ts +5 -0
  25. package/openapi/gen/models/trainingRunMetricHistory.ts +9 -0
  26. package/openapi/gen/models/trainingRunMetricHistoryMetric.ts +2 -0
  27. package/openapi/gen/models/trainingRunMetricHistoryPointsItem.ts +9 -0
  28. package/openapi/gen/models/trainingRunMetricHistoryPointsItemNonFinite.ts +2 -0
  29. package/openapi/gen/models/trainingRunMetricHistoryPointsItemValue.ts +2 -0
  30. package/openapi/gen/models/trainingRunMetrics.ts +9 -0
  31. package/openapi/gen/models/trainingRunMetricsMetricsItem.ts +8 -0
  32. package/openapi/gen/models/trainingRunMetricsMetricsItemLatest.ts +9 -0
  33. package/openapi/gen/models/trainingRunMetricsMetricsItemLatestNonFinite.ts +2 -0
  34. package/openapi/gen/models/trainingRunMetricsMetricsItemLatestValue.ts +2 -0
  35. package/openapi/gen/models/trainingRunMetricsMetricsItemMetric.ts +2 -0
  36. package/openapi/gen/models/trainingRunMetricsUnavailableReason.ts +2 -0
  37. package/package.json +2 -2
  38. package/skills/catalog.json +55 -7
  39. package/skills/toloka-build/SKILL.md +10 -7
  40. package/skills/toloka-build/references/node-semantics.md +6 -4
  41. package/skills/toloka-build/references/workflow-and-cli.md +21 -13
  42. package/skills/toloka-fine-tuning/SKILL.md +72 -0
  43. package/skills/toloka-get-started/SKILL.md +55 -0
  44. package/skills/toloka-gisting/SKILL.md +76 -0
  45. package/skills/toloka-report-issue/references/report-template.md +1 -1
  46. package/src/authoring/index.ts +14 -0
  47. package/src/checks/task-ui-typecheck.ts +12 -10
  48. package/src/cli/analytics.ts +52 -6
  49. package/src/cli/auth.ts +69 -16
  50. package/src/cli/auto-update.ts +24 -33
  51. package/src/cli/check.ts +12 -10
  52. package/src/cli/commands/auth.ts +89 -0
  53. package/src/cli/commands/config.ts +28 -0
  54. package/src/cli/commands/dataset.ts +75 -0
  55. package/src/cli/commands/delivery-order.ts +18 -0
  56. package/src/cli/commands/models.ts +122 -0
  57. package/src/cli/commands/pipeline.ts +132 -0
  58. package/src/cli/commands/project.ts +175 -0
  59. package/src/cli/commands/report.ts +39 -0
  60. package/src/cli/commands/secret.ts +39 -0
  61. package/src/cli/commands/skill.ts +36 -0
  62. package/src/cli/commands/source.ts +204 -0
  63. package/src/cli/commands/status.ts +18 -0
  64. package/src/cli/commands/training.ts +228 -0
  65. package/src/cli/commands/version.ts +14 -0
  66. package/src/cli/config.ts +5 -6
  67. package/src/cli/context.ts +213 -0
  68. package/src/cli/delivery-orders.ts +30 -0
  69. package/src/cli/environment.ts +26 -0
  70. package/src/cli/init.ts +1 -4
  71. package/src/cli/program.ts +168 -1344
  72. package/src/cli/project-context.ts +9 -11
  73. package/src/cli/sdk-version.ts +38 -0
  74. package/src/cli/skill.ts +6 -2
  75. package/src/cli/terminal-io.ts +103 -0
  76. package/src/cli/trainings.ts +118 -27
  77. package/src/cli/version.ts +1 -1
  78. package/src/client.ts +18 -0
  79. package/src/importer.ts +32 -2
@@ -0,0 +1,213 @@
1
+ import { InvalidArgumentError, type Command } from "commander";
2
+ import { resolve } from "node:path";
3
+ import { createClient } from "../client";
4
+ import type { PotatoClient } from "../client";
5
+ import { readTolokaState } from "../state";
6
+ import type { TolokaState } from "../state";
7
+ import type { AuthPrompt } from "./auth";
8
+ import type { CliAnalytics } from "./analytics";
9
+ import type { checkProject } from "./check";
10
+ import { PRODUCTION_BASE_URL, resolveTolokaConfig } from "./config";
11
+ import type { TolokaEnvironment } from "./config";
12
+ import { findCommandCredentials } from "./credentials";
13
+ import type { StoredCredentials } from "./credentials";
14
+ import { resolveProjectContext } from "./project-context";
15
+ import { findSourceRoot } from "./source";
16
+ import type { TrainingDraftOptions } from "./trainings";
17
+ import type { RunOutcome } from "./runs";
18
+
19
+ export type CliIo = {
20
+ readonly stdout: (text: string) => void;
21
+ readonly stderr: (text: string) => void;
22
+ readonly readStdin: () => Promise<string>;
23
+ readonly prompt?: AuthPrompt;
24
+ readonly select?: (choices: readonly { name: string; value: string }[]) => Promise<string>;
25
+ };
26
+
27
+ export type ProgramContext = {
28
+ readonly environment: TolokaEnvironment;
29
+ readonly io: CliIo;
30
+ readonly injectedClient?: PotatoClient;
31
+ readonly runChecks?: typeof checkProject;
32
+ readonly analytics?: CliAnalytics;
33
+ readonly internalUser?: boolean;
34
+ };
35
+
36
+ export type GlobalOptions = {
37
+ readonly sourceRoot?: string;
38
+ readonly apiKey?: string;
39
+ readonly baseUrl?: string;
40
+ readonly projectId?: string;
41
+ };
42
+
43
+ export type CreatedProgram = {
44
+ readonly program: Command;
45
+ readonly exitCode: { value: number };
46
+ };
47
+
48
+ export type Resolved = {
49
+ readonly sourceRoot: string;
50
+ readonly client: PotatoClient;
51
+ readonly baseUrl: string;
52
+ readonly state: TolokaState | undefined;
53
+ readonly stored: StoredCredentials | undefined;
54
+ readonly projectId?: string;
55
+ };
56
+
57
+ export const CREDENTIAL_PRECEDENCE = [
58
+ "Credentials resolve in this order, highest first:",
59
+ " 1. --api-key / --base-url",
60
+ " 2. TOLOKA_API_KEY / TOLOKA_BASE_URL",
61
+ " 3. the file written by toloka login",
62
+ `The platform defaults to ${PRODUCTION_BASE_URL}.`,
63
+ ].join("\n");
64
+
65
+ export const authoredByOption = (raw: string): "human" | "agent" => {
66
+ if (raw !== "human" && raw !== "agent")
67
+ throw new InvalidArgumentError('Expected "human" or "agent".');
68
+ return raw;
69
+ };
70
+
71
+ export const positiveInteger = (raw: string): number => {
72
+ const value = Number(raw);
73
+ if (!Number.isInteger(value) || value <= 0)
74
+ throw new InvalidArgumentError("Expected a positive integer.");
75
+ return value;
76
+ };
77
+
78
+ export const nonNegativeInteger = (raw: string): number => {
79
+ const value = Number(raw);
80
+ if (!Number.isInteger(value) || value < 0)
81
+ throw new InvalidArgumentError("Expected a non-negative integer.");
82
+ return value;
83
+ };
84
+
85
+ export const trainingMethod = (raw: string): "sft" | "gisting" => {
86
+ if (raw !== "sft" && raw !== "gisting") {
87
+ throw new InvalidArgumentError('Expected training method "sft" or "gisting".');
88
+ }
89
+ return raw;
90
+ };
91
+
92
+ export const trainingRegime = (raw: string): "low" | "medium" | "high" => {
93
+ if (raw !== "low" && raw !== "medium" && raw !== "high") {
94
+ throw new InvalidArgumentError('Expected regime "low", "medium", or "high".');
95
+ }
96
+ return raw;
97
+ };
98
+
99
+ export type RawTrainingDraftOptions = {
100
+ method?: TrainingDraftOptions["method"];
101
+ baseModel?: TrainingDraftOptions["baseModelId"];
102
+ modelVersion?: string;
103
+ dataset?: string;
104
+ validationDataset?: string;
105
+ trainFilter?: string;
106
+ validationFilter?: string;
107
+ regime?: TrainingDraftOptions["regime"];
108
+ epochs?: number;
109
+ evalSteps?: number;
110
+ promptFile?: string;
111
+ };
112
+
113
+ export const trainingDraftOptions = (options: RawTrainingDraftOptions): TrainingDraftOptions => ({
114
+ method: options.method,
115
+ baseModelId: options.baseModel,
116
+ modelVersionId: options.modelVersion,
117
+ datasetId: options.dataset,
118
+ validationDatasetId: options.validationDataset,
119
+ trainingFilter: options.trainFilter,
120
+ validationFilter: options.validationFilter,
121
+ regime: options.regime,
122
+ epochs: options.epochs,
123
+ evalSteps: options.evalSteps,
124
+ promptFilePath: options.promptFile,
125
+ });
126
+
127
+ export const exitCodeForOutcome = (outcome: RunOutcome): number => {
128
+ if (outcome === "failed") return 1;
129
+ if (outcome === "timedOut") return 2;
130
+ return 0;
131
+ };
132
+
133
+ export const resolveSourceRoot = async (globals: GlobalOptions, io: CliIo): Promise<string> => {
134
+ if (globals.sourceRoot !== undefined) return resolve(globals.sourceRoot);
135
+
136
+ const workingDirectory = process.cwd();
137
+ const discovered = await findSourceRoot(workingDirectory);
138
+ if (discovered === undefined || discovered === workingDirectory) return workingDirectory;
139
+
140
+ io.stderr(`Using project root ${discovered} (found from ${workingDirectory}).`);
141
+ return discovered;
142
+ };
143
+
144
+ export const resolveInitRoot = (globals: GlobalOptions): string =>
145
+ globals.sourceRoot === undefined ? process.cwd() : resolve(globals.sourceRoot);
146
+
147
+ export const readCommandCredentials = async (globals: GlobalOptions, context: ProgramContext) => {
148
+ const { found, warning } = await findCommandCredentials(
149
+ context.environment,
150
+ globals.apiKey ?? context.environment.TOLOKA_API_KEY,
151
+ );
152
+ if (warning !== undefined) context.io.stderr(warning);
153
+ return found?.credentials;
154
+ };
155
+
156
+ export const identifyClientUser = async (
157
+ client: PotatoClient,
158
+ analytics: CliAnalytics | undefined,
159
+ ) => {
160
+ if (analytics?.shouldIdentify !== true) return;
161
+ try {
162
+ analytics.identifyCurrentUser(await client.me());
163
+ } catch {}
164
+ };
165
+
166
+ export const resolveInternalUser = async (client: PotatoClient): Promise<boolean | undefined> => {
167
+ try {
168
+ return (await client.me()).internal;
169
+ } catch {
170
+ return undefined;
171
+ }
172
+ };
173
+
174
+ export const resolveContext = async (
175
+ globals: GlobalOptions,
176
+ context: ProgramContext,
177
+ ): Promise<Resolved> => {
178
+ const sourceRoot = await resolveSourceRoot(globals, context.io);
179
+ const state = await readTolokaState(sourceRoot);
180
+ const stored = await readCommandCredentials(globals, context);
181
+ const config = resolveTolokaConfig(globals, state, context.environment, stored);
182
+ const client =
183
+ context.injectedClient ?? createClient({ apiKey: config.apiKey, baseUrl: config.baseUrl });
184
+ await identifyClientUser(client, context.analytics);
185
+
186
+ return {
187
+ sourceRoot,
188
+ client,
189
+ baseUrl: config.baseUrl,
190
+ state,
191
+ stored,
192
+ ...(config.projectId === undefined ? {} : { projectId: config.projectId }),
193
+ };
194
+ };
195
+
196
+ export const resolveSelectedProject = (
197
+ globals: GlobalOptions,
198
+ context: ProgramContext,
199
+ stored: StoredCredentials | undefined,
200
+ state: TolokaState | undefined,
201
+ ) =>
202
+ resolveProjectContext({
203
+ flags: globals,
204
+ environment: context.environment,
205
+ stored,
206
+ ...(state === undefined ? {} : { state }),
207
+ });
208
+
209
+ export type CommandHost = {
210
+ readonly context: ProgramContext;
211
+ readonly exitCode: { value: number };
212
+ readonly globals: () => GlobalOptions;
213
+ };
@@ -0,0 +1,30 @@
1
+ export type DeliveryOrderRecord = {
2
+ readonly id: string;
3
+ readonly name: string;
4
+ readonly mondayId: string;
5
+ readonly status: string;
6
+ readonly clientName: string | null;
7
+ };
8
+
9
+ export type DeliveryOrderListApi = {
10
+ readonly deliveryOrders: {
11
+ readonly list: () => Promise<readonly DeliveryOrderRecord[]>;
12
+ };
13
+ };
14
+
15
+ export async function listDeliveryOrders(options: {
16
+ readonly client: DeliveryOrderListApi;
17
+ }): Promise<{ readonly output: string }> {
18
+ const orders = await options.client.deliveryOrders.list();
19
+ if (orders.length === 0) {
20
+ return { output: "No delivery orders visible." };
21
+ }
22
+ return {
23
+ output: [
24
+ "ID\tNAME\tSTATUS\tCLIENT",
25
+ ...orders.map(
26
+ (order) => `${order.id}\t${order.name}\t${order.status}\t${order.clientName ?? "-"}`,
27
+ ),
28
+ ].join("\n"),
29
+ };
30
+ }
@@ -0,0 +1,26 @@
1
+ import type { TolokaEnvironment } from "./config";
2
+
3
+ const LEGACY_ENVIRONMENT_NAMES: Readonly<Record<string, string>> = {
4
+ POTATO_API_KEY: "TOLOKA_API_KEY",
5
+ POTATO_BASE_URL: "TOLOKA_BASE_URL",
6
+ POTATO_PROJECT_ID: "TOLOKA_PROJECT_ID",
7
+ };
8
+
9
+ export const API_KEY_ENVIRONMENT_NAMES = ["TOLOKA_API_KEY", "POTATO_API_KEY"];
10
+
11
+ export type NormalizedEnvironment = {
12
+ readonly environment: TolokaEnvironment;
13
+ readonly warnings: readonly string[];
14
+ };
15
+
16
+ export const normalizeEnvironment = (environment: TolokaEnvironment): NormalizedEnvironment => {
17
+ const normalized: Record<string, string | undefined> = { ...environment };
18
+ const warnings: string[] = [];
19
+ for (const [legacy, current] of Object.entries(LEGACY_ENVIRONMENT_NAMES)) {
20
+ const value = environment[legacy];
21
+ if (value === undefined) continue;
22
+ normalized[current] ??= value;
23
+ warnings.push(`${legacy} is deprecated and will stop being read; set ${current} instead.`);
24
+ }
25
+ return { environment: normalized, warnings };
26
+ };
package/src/cli/init.ts CHANGED
@@ -1,14 +1,11 @@
1
1
  import { assert } from "es-toolkit";
2
2
  import { lstat, mkdir, readdir, readFile, realpath, rm, rmdir, writeFile } from "node:fs/promises";
3
3
  import { dirname, join } from "node:path";
4
- import packageMetadata from "../../package.json" with { type: "json" };
5
4
  import { readTolokaState, writeTolokaState } from "../state";
6
5
  import { assertSafeDestination, entryStats, isMissingFileError } from "./file-system";
6
+ import { SDK_PACKAGE_NAME, SDK_VERSION } from "./sdk-version";
7
7
  import { SKILL_ENTRY_POINT, SKILL_INSTALL_ROOT } from "./skill";
8
8
 
9
- export const SDK_VERSION = packageMetadata.version;
10
-
11
- const SDK_PACKAGE_NAME = "@toloka-platform/sdk";
12
9
  const BOOTSTRAP_NAME = "toloka-bootstrap";
13
10
  const CLAUDE_POINTER_PATH = `.claude/skills/${BOOTSTRAP_NAME}/SKILL.md`;
14
11
  const CURSOR_POINTER_PATH = `.cursor/rules/${BOOTSTRAP_NAME}.mdc`;