@toloka-platform/sdk 0.2.0-preview.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -6
- package/dist/cli/toloka.js +136 -136
- 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 +3 -2
- package/docs/cli.md +35 -7
- package/docs/getting-started.md +4 -2
- package/docs/limitations.md +2 -2
- package/openapi/gen/models/baseModel.ts +1 -0
- package/openapi/gen/models/currentUser.ts +2 -0
- package/openapi/gen/models/currentUserTeamsItem.ts +6 -0
- package/openapi/gen/models/gistingTrainingConfiguration.ts +6 -2
- package/openapi/gen/models/gistingTrainingConfigurationBatchSize.ts +2 -0
- package/openapi/gen/models/gistingTrainingConfigurationGistTokens.ts +2 -0
- package/openapi/gen/models/gistingTrainingConfigurationInput.ts +6 -2
- package/openapi/gen/models/gistingTrainingConfigurationInputBatchSize.ts +2 -0
- package/openapi/gen/models/gistingTrainingConfigurationInputGistTokens.ts +2 -0
- package/openapi/gen/models/index.ts +9 -4
- package/openapi/gen/models/sftTrainingConfiguration.ts +6 -3
- package/openapi/gen/models/sftTrainingConfigurationBatchSize.ts +2 -0
- package/openapi/gen/models/sftTrainingConfigurationInput.ts +6 -3
- package/openapi/gen/models/sftTrainingConfigurationInputBatchSize.ts +2 -0
- package/openapi/gen/models/sftTrainingConfigurationInputLoraRank.ts +2 -0
- package/openapi/gen/models/sftTrainingConfigurationLoraRank.ts +2 -0
- package/package.json +2 -2
- package/skills/catalog.json +11 -11
- package/skills/toloka-build/SKILL.md +29 -18
- package/skills/toloka-build/references/node-semantics.md +7 -7
- package/skills/toloka-build/references/workflow-and-cli.md +15 -12
- package/skills/toloka-fine-tuning/SKILL.md +145 -62
- package/skills/toloka-get-started/SKILL.md +37 -21
- package/skills/toloka-gisting/SKILL.md +156 -66
- package/skills/toloka-report-issue/references/report-template.md +1 -1
- package/src/cli/analytics.ts +50 -23
- package/src/cli/auth.ts +31 -12
- package/src/cli/auto-update.ts +12 -6
- package/src/cli/check.ts +76 -29
- package/src/cli/cli-entry.ts +3 -2
- package/src/cli/cli-error.ts +43 -0
- package/src/cli/commands/dataset.ts +13 -3
- package/src/cli/commands/models.ts +6 -7
- package/src/cli/commands/pipeline.ts +6 -7
- package/src/cli/commands/project.ts +9 -16
- package/src/cli/commands/report.ts +6 -2
- package/src/cli/commands/secret.ts +5 -4
- package/src/cli/commands/source.ts +4 -4
- package/src/cli/commands/status.ts +2 -3
- package/src/cli/commands/training.ts +50 -17
- package/src/cli/config.ts +2 -2
- package/src/cli/context.ts +55 -17
- package/src/cli/credentials.ts +12 -4
- package/src/cli/data.ts +96 -34
- package/src/cli/delivery-orders.ts +18 -1
- package/src/cli/file-system.ts +6 -2
- package/src/cli/format-error.ts +45 -2
- package/src/cli/init.ts +13 -7
- package/src/cli/models.ts +43 -12
- package/src/cli/program.ts +5 -56
- package/src/cli/project-context.ts +117 -32
- package/src/cli/project.ts +80 -28
- package/src/cli/report.ts +24 -9
- package/src/cli/runs.ts +33 -8
- package/src/cli/settings.ts +13 -5
- package/src/cli/skill.ts +61 -22
- package/src/cli/source.ts +3 -2
- package/src/cli/terminal-io.ts +13 -6
- package/src/cli/trainings.ts +129 -35
- package/src/cli/version.ts +2 -2
- package/src/client.ts +3 -9
- package/src/transport.ts +13 -1
- package/openapi/gen/models/gistingTrainingConfigurationInputRegime.ts +0 -2
- package/openapi/gen/models/gistingTrainingConfigurationRegime.ts +0 -2
- package/openapi/gen/models/sftTrainingConfigurationInputRegime.ts +0 -2
- package/openapi/gen/models/sftTrainingConfigurationRegime.ts +0 -2
package/src/cli/format-error.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PotatoApiError } from "../errors";
|
|
2
|
+
import { formatHint, TolokaCliError } from "./cli-error";
|
|
2
3
|
|
|
3
4
|
export const apiErrorDetails = (error: PotatoApiError): string | undefined => {
|
|
4
5
|
const details =
|
|
@@ -10,10 +11,52 @@ export const apiErrorDetails = (error: PotatoApiError): string | undefined => {
|
|
|
10
11
|
return details === undefined || details.length === 0 ? undefined : details;
|
|
11
12
|
};
|
|
12
13
|
|
|
14
|
+
const apiErrorHint = (error: PotatoApiError): string | undefined => {
|
|
15
|
+
if (error.code === "wait_timeout") {
|
|
16
|
+
return "Hint: The job is still running. Check it later with its status command; commands that accept --timeout can wait longer.";
|
|
17
|
+
}
|
|
18
|
+
if (error.status === 401 || error.status === 403) {
|
|
19
|
+
return "Hint: Run toloka whoami to see which key and platform are in use; toloka login stores a new key.";
|
|
20
|
+
}
|
|
21
|
+
if (error.status === 404) {
|
|
22
|
+
return "Hint: Check the id against toloka project current and the matching list command; ids belong to one project on one platform.";
|
|
23
|
+
}
|
|
24
|
+
if (error.status === 429) {
|
|
25
|
+
return "Hint: The platform is rate limiting this key; wait a moment and retry.";
|
|
26
|
+
}
|
|
27
|
+
if (error.status !== undefined && error.status >= 500) {
|
|
28
|
+
return "Hint: The platform failed to handle the request. Retry; if it keeps failing, write a report as the toloka-report-issue skill describes and send it with toloka report <report.md>.";
|
|
29
|
+
}
|
|
30
|
+
return undefined;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const joinLines = (lines: ReadonlyArray<string | undefined>): string =>
|
|
34
|
+
lines.filter((line) => line !== undefined && line.length > 0).join("\n");
|
|
35
|
+
|
|
36
|
+
export const findPotatoApiError = (error: unknown): PotatoApiError | undefined => {
|
|
37
|
+
if (error instanceof PotatoApiError) return error;
|
|
38
|
+
if (error instanceof AggregateError) {
|
|
39
|
+
for (const nested of error.errors) {
|
|
40
|
+
const apiError = findPotatoApiError(nested);
|
|
41
|
+
if (apiError !== undefined) return apiError;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return error instanceof Error ? findPotatoApiError(error.cause) : undefined;
|
|
45
|
+
};
|
|
46
|
+
|
|
13
47
|
export const formatCliError = (error: unknown): string => {
|
|
48
|
+
if (error instanceof TolokaCliError) {
|
|
49
|
+
const cause = findPotatoApiError(error.cause);
|
|
50
|
+
const causeLines =
|
|
51
|
+
cause === undefined
|
|
52
|
+
? []
|
|
53
|
+
: cause.message === error.message
|
|
54
|
+
? [apiErrorDetails(cause)]
|
|
55
|
+
: [cause.message, apiErrorDetails(cause)];
|
|
56
|
+
return joinLines([error.message, ...causeLines, formatHint(error.hint)]);
|
|
57
|
+
}
|
|
14
58
|
if (error instanceof PotatoApiError) {
|
|
15
|
-
|
|
16
|
-
return details === undefined ? error.message : `${error.message}\n${details}`;
|
|
59
|
+
return joinLines([error.message, apiErrorDetails(error), apiErrorHint(error)]);
|
|
17
60
|
}
|
|
18
61
|
return error instanceof Error ? error.message : String(error);
|
|
19
62
|
};
|
package/src/cli/init.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { assert } from "es-toolkit";
|
|
2
1
|
import { lstat, mkdir, readdir, readFile, realpath, rm, rmdir, writeFile } from "node:fs/promises";
|
|
3
2
|
import { dirname, join } from "node:path";
|
|
4
3
|
import { readTolokaState, writeTolokaState } from "../state";
|
|
5
4
|
import { assertSafeDestination, entryStats, isMissingFileError } from "./file-system";
|
|
6
5
|
import { SDK_PACKAGE_NAME, SDK_VERSION } from "./sdk-version";
|
|
7
6
|
import { SKILL_ENTRY_POINT, SKILL_INSTALL_ROOT } from "./skill";
|
|
7
|
+
import { assertCli } from "./cli-error";
|
|
8
8
|
|
|
9
9
|
const BOOTSTRAP_NAME = "toloka-bootstrap";
|
|
10
10
|
const CLAUDE_POINTER_PATH = `.claude/skills/${BOOTSTRAP_NAME}/SKILL.md`;
|
|
@@ -106,14 +106,16 @@ const locateBlock = (source: string, markers: BlockMarkers, path: string) => {
|
|
|
106
106
|
const beginIndex = source.indexOf(markers.begin);
|
|
107
107
|
const endIndex = source.indexOf(markers.end);
|
|
108
108
|
if (beginIndex === -1 && endIndex === -1) return undefined;
|
|
109
|
-
|
|
109
|
+
assertCli(
|
|
110
110
|
beginIndex !== -1 && endIndex !== -1 && beginIndex < endIndex,
|
|
111
111
|
`Malformed Toloka block in ${path}: expected one ${markers.begin} followed by one ${markers.end}. Repair the file by hand, then re-run \`toloka init\`.`,
|
|
112
|
+
{ hint: { disabled: true } },
|
|
112
113
|
);
|
|
113
|
-
|
|
114
|
+
assertCli(
|
|
114
115
|
!source.includes(markers.begin, beginIndex + markers.begin.length) &&
|
|
115
116
|
!source.includes(markers.end, endIndex + markers.end.length),
|
|
116
117
|
`Multiple Toloka blocks in ${path}: keep exactly one ${markers.begin} ... ${markers.end} block, then re-run \`toloka init\`.`,
|
|
118
|
+
{ hint: { disabled: true } },
|
|
117
119
|
);
|
|
118
120
|
return { beginIndex, endIndex: endIndex + markers.end.length };
|
|
119
121
|
};
|
|
@@ -121,9 +123,10 @@ const locateBlock = (source: string, markers: BlockMarkers, path: string) => {
|
|
|
121
123
|
const mergeBootstrap = (source: string, path: string) => {
|
|
122
124
|
const current = locateBlock(source, CURRENT_BLOCK, path);
|
|
123
125
|
const legacy = locateBlock(source, LEGACY_BLOCK, path);
|
|
124
|
-
|
|
126
|
+
assertCli(
|
|
125
127
|
current === undefined || legacy === undefined,
|
|
126
128
|
`Ambiguous Toloka blocks in ${path}: both ${CURRENT_BLOCK.begin} and ${LEGACY_BLOCK.begin} are present. Keep one, then re-run \`toloka init\`.`,
|
|
129
|
+
{ hint: { disabled: true } },
|
|
127
130
|
);
|
|
128
131
|
const lineEnding = source.includes("\r\n") ? "\r\n" : "\n";
|
|
129
132
|
const block = BOOTSTRAP_BLOCK.replaceAll("\n", lineEnding);
|
|
@@ -146,9 +149,10 @@ const hasSdkDependency = async (targetDirectory: string) => {
|
|
|
146
149
|
const source = await readOptionalFile(join(targetDirectory, "package.json"));
|
|
147
150
|
if (source === undefined) return false;
|
|
148
151
|
const manifest: unknown = JSON.parse(source);
|
|
149
|
-
|
|
152
|
+
assertCli(
|
|
150
153
|
typeof manifest === "object" && manifest !== null,
|
|
151
154
|
"package.json must contain a JSON object.",
|
|
155
|
+
{ hint: { description: "Fix package.json in the source root, then re-run toloka init." } },
|
|
152
156
|
);
|
|
153
157
|
return ["dependencies", "devDependencies"].some((key) => {
|
|
154
158
|
const dependencies = Reflect.get(manifest, key);
|
|
@@ -170,9 +174,10 @@ const writeIfChanged = async (path: string, source: string) => {
|
|
|
170
174
|
const assertRefreshablePointer = async (targetRoot: string, relativePath: string) => {
|
|
171
175
|
const path = join(targetRoot, relativePath);
|
|
172
176
|
const existing = await readOptionalFile(path);
|
|
173
|
-
|
|
177
|
+
assertCli(
|
|
174
178
|
existing === undefined || isGenerated(existing),
|
|
175
179
|
`Refusing to overwrite ${path}: it carries no \`<!-- toloka:sdk-version ... -->\` marker, so it is not a pointer generated by ${SDK_PACKAGE_NAME}. Move it aside, then re-run \`toloka init\`.`,
|
|
180
|
+
{ hint: { disabled: true } },
|
|
176
181
|
);
|
|
177
182
|
};
|
|
178
183
|
|
|
@@ -215,9 +220,10 @@ const bindCheckout = async (
|
|
|
215
220
|
): Promise<string | undefined> => {
|
|
216
221
|
if (projectId === undefined) return undefined;
|
|
217
222
|
const existing = await readTolokaState(targetRoot);
|
|
218
|
-
|
|
223
|
+
assertCli(
|
|
219
224
|
existing === undefined || existing.projectId === projectId,
|
|
220
225
|
`This directory is already bound to ${existing?.projectId}.`,
|
|
226
|
+
{ hint: { description: "Run toloka init without --project-id to keep the current binding, or remove toloka.json to bind another project." } },
|
|
221
227
|
);
|
|
222
228
|
if (existing !== undefined) return undefined;
|
|
223
229
|
await writeTolokaState(targetRoot, { projectId, pipelines: {}, datasets: {} });
|
package/src/cli/models.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { isAbsolute, relative, resolve, sep } from "node:path";
|
|
|
5
5
|
import { Readable, Transform } from "node:stream";
|
|
6
6
|
import { pipeline } from "node:stream/promises";
|
|
7
7
|
|
|
8
|
-
import { assert } from "es-toolkit";
|
|
9
8
|
|
|
10
9
|
import type { BaseModel, BaseModelId, Model, ModelVersion, PotatoClient } from "../client";
|
|
10
|
+
import { assertCli, REPORT_HINT, RETRY_OR_REPORT_HINT } from "./cli-error";
|
|
11
11
|
|
|
12
12
|
type ModelApi = Pick<PotatoClient, "baseModels" | "models">;
|
|
13
13
|
type ModelIo = { readonly stdout: (text: string) => void };
|
|
@@ -46,6 +46,7 @@ const formatBaseModel = (model: BaseModel): string =>
|
|
|
46
46
|
["Provider", model.provider],
|
|
47
47
|
["Upstream model", model.upstreamModel],
|
|
48
48
|
["Upstream revision", model.upstreamRevision],
|
|
49
|
+
["Upstream snapshot", model.upstreamUrl],
|
|
49
50
|
]);
|
|
50
51
|
|
|
51
52
|
const formatModel = (model: Model): string =>
|
|
@@ -62,7 +63,11 @@ const formatModel = (model: Model): string =>
|
|
|
62
63
|
|
|
63
64
|
export const parseBaseModelId = (value: string): BaseModelId => {
|
|
64
65
|
const modelId = BASE_MODEL_IDS.find((candidate) => candidate === value);
|
|
65
|
-
|
|
66
|
+
assertCli(
|
|
67
|
+
modelId,
|
|
68
|
+
`Unknown base model ${value}.`,
|
|
69
|
+
{ hint: { description: "Run toloka base-model list to see the catalog." } },
|
|
70
|
+
);
|
|
66
71
|
return modelId;
|
|
67
72
|
};
|
|
68
73
|
|
|
@@ -76,7 +81,11 @@ const resolveModel = async (
|
|
|
76
81
|
for await (const model of client.models.listAll({ projectId, limit: 100 })) {
|
|
77
82
|
if (model.name === nameOrId) matches.push(model);
|
|
78
83
|
}
|
|
79
|
-
|
|
84
|
+
assertCli(
|
|
85
|
+
matches.length === 1,
|
|
86
|
+
`Model ${nameOrId} was not found or is ambiguous.`,
|
|
87
|
+
{ hint: { description: "Run toloka model list and pass the model id (mdl.…)." } },
|
|
88
|
+
);
|
|
80
89
|
return matches[0]!;
|
|
81
90
|
};
|
|
82
91
|
|
|
@@ -87,8 +96,16 @@ const resolveModelVersion = async (
|
|
|
87
96
|
): Promise<ModelVersion> => {
|
|
88
97
|
if (nameOrId.startsWith("mdv.")) return client.models.getVersion({ modelVersionId: nameOrId });
|
|
89
98
|
const separator = nameOrId.lastIndexOf("@");
|
|
90
|
-
|
|
91
|
-
|
|
99
|
+
assertCli(
|
|
100
|
+
separator > 0,
|
|
101
|
+
`Model Version ${nameOrId} was not found. Use mdv.<id> or Model@name.`,
|
|
102
|
+
{ hint: { disabled: true } },
|
|
103
|
+
);
|
|
104
|
+
assertCli(
|
|
105
|
+
projectId,
|
|
106
|
+
"Select a project to resolve Model Version names.",
|
|
107
|
+
{ hint: { description: "Select a project with toloka project add or toloka project switch, or pass the version id (mdv.…) directly." } },
|
|
108
|
+
);
|
|
92
109
|
const model = await resolveModel(client, projectId, nameOrId.slice(0, separator));
|
|
93
110
|
const versionName = nameOrId.slice(separator + 1);
|
|
94
111
|
const matches: ModelVersion[] = [];
|
|
@@ -99,7 +116,11 @@ const resolveModelVersion = async (
|
|
|
99
116
|
})) {
|
|
100
117
|
if (version.name === versionName) matches.push(version);
|
|
101
118
|
}
|
|
102
|
-
|
|
119
|
+
assertCli(
|
|
120
|
+
matches.length === 1,
|
|
121
|
+
`Model Version ${nameOrId} was not found or is ambiguous.`,
|
|
122
|
+
{ hint: { description: "Run toloka model versions <model> and pass the version id (mdv.…)." } },
|
|
123
|
+
);
|
|
103
124
|
return matches[0]!;
|
|
104
125
|
};
|
|
105
126
|
|
|
@@ -116,12 +137,14 @@ export const listBaseModels = async (
|
|
|
116
137
|
models.length === 0
|
|
117
138
|
? "No base models found."
|
|
118
139
|
: formatTable([
|
|
119
|
-
["ID", "NAME", "PROVIDER", "UPSTREAM MODEL"],
|
|
140
|
+
["ID", "NAME", "PROVIDER", "UPSTREAM MODEL", "REVISION", "UPSTREAM SNAPSHOT"],
|
|
120
141
|
...models.map((model) => [
|
|
121
142
|
model.id,
|
|
122
143
|
model.displayName,
|
|
123
144
|
model.provider,
|
|
124
145
|
model.upstreamModel,
|
|
146
|
+
model.upstreamRevision.slice(0, 12),
|
|
147
|
+
model.upstreamUrl,
|
|
125
148
|
]),
|
|
126
149
|
]),
|
|
127
150
|
);
|
|
@@ -238,25 +261,31 @@ export const downloadModelVersion = async (
|
|
|
238
261
|
for (const file of descriptor.files) {
|
|
239
262
|
const target = resolve(root, file.path);
|
|
240
263
|
const relativeTarget = relative(root, target);
|
|
241
|
-
|
|
264
|
+
assertCli(
|
|
242
265
|
relativeTarget !== "" &&
|
|
243
266
|
relativeTarget !== ".." &&
|
|
244
267
|
!relativeTarget.startsWith(`..${sep}`) &&
|
|
245
268
|
!isAbsolute(relativeTarget),
|
|
246
269
|
`Invalid Model Version file path: ${file.path}`,
|
|
270
|
+
{ hint: REPORT_HINT },
|
|
247
271
|
);
|
|
248
272
|
let parent = root;
|
|
249
273
|
for (const segment of file.path.split("/").slice(0, -1)) {
|
|
250
274
|
parent = resolve(parent, segment);
|
|
251
275
|
await mkdir(parent, { recursive: true });
|
|
252
276
|
const realParent = await realpath(parent);
|
|
253
|
-
|
|
277
|
+
assertCli(
|
|
254
278
|
realParent === realRoot || realParent.startsWith(`${realRoot}${sep}`),
|
|
255
279
|
`Invalid Model Version file path: ${file.path}`,
|
|
280
|
+
{ hint: REPORT_HINT },
|
|
256
281
|
);
|
|
257
282
|
}
|
|
258
283
|
const response = await fetch(file.url, { redirect: "error" });
|
|
259
|
-
|
|
284
|
+
assertCli(
|
|
285
|
+
response.ok && response.body,
|
|
286
|
+
`Failed to download Model Version file ${file.path}.`,
|
|
287
|
+
{ hint: RETRY_OR_REPORT_HINT },
|
|
288
|
+
);
|
|
260
289
|
const hash = createHash("sha256");
|
|
261
290
|
let byteSize = 0;
|
|
262
291
|
const verify = new Transform({
|
|
@@ -274,13 +303,15 @@ export const downloadModelVersion = async (
|
|
|
274
303
|
0o600,
|
|
275
304
|
);
|
|
276
305
|
await pipeline(Readable.from(response.body), verify, handle.createWriteStream());
|
|
277
|
-
|
|
306
|
+
assertCli(
|
|
278
307
|
byteSize === file.byteSize,
|
|
279
308
|
`Downloaded Model Version file ${file.path} has an unexpected size.`,
|
|
309
|
+
{ hint: { description: "Delete the partial download and retry; if it keeps failing, run toloka report." } },
|
|
280
310
|
);
|
|
281
|
-
|
|
311
|
+
assertCli(
|
|
282
312
|
hash.digest("hex") === file.sha256,
|
|
283
313
|
`Downloaded Model Version file ${file.path} has an invalid hash.`,
|
|
314
|
+
{ hint: { description: "Delete the partial download and retry; if it keeps failing, run toloka report." } },
|
|
284
315
|
);
|
|
285
316
|
await rename(temporary, target);
|
|
286
317
|
} catch (error) {
|
package/src/cli/program.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, CommanderError } from "commander";
|
|
2
|
-
import {
|
|
2
|
+
import type { PotatoClient } from "../client";
|
|
3
3
|
import { commandNameFromArgv, createCliAnalytics } from "./analytics";
|
|
4
4
|
import type { CliAnalytics, CliAnalyticsCommandOutcome } from "./analytics";
|
|
5
5
|
import type { AutoUpdateHooks } from "./auto-update";
|
|
@@ -19,11 +19,9 @@ import { registerSourceCommands } from "./commands/source";
|
|
|
19
19
|
import { registerStatusCommand } from "./commands/status";
|
|
20
20
|
import { registerTrainingCommands } from "./commands/training";
|
|
21
21
|
import { registerVersionCommand } from "./commands/version";
|
|
22
|
-
import {
|
|
23
|
-
import { findCommandCredentials } from "./credentials";
|
|
22
|
+
import type { TolokaEnvironment } from "./config";
|
|
24
23
|
import {
|
|
25
24
|
CREDENTIAL_PRECEDENCE,
|
|
26
|
-
resolveInternalUser,
|
|
27
25
|
resolveSourceRoot,
|
|
28
26
|
type CliIo,
|
|
29
27
|
type CreatedProgram,
|
|
@@ -39,51 +37,6 @@ import { terminalIo } from "./terminal-io";
|
|
|
39
37
|
export type { CliIo, CreatedProgram, ProgramContext } from "./context";
|
|
40
38
|
export { terminalIo } from "./terminal-io";
|
|
41
39
|
|
|
42
|
-
const argvFlag = (argv: readonly string[], flag: string): string | undefined => {
|
|
43
|
-
const index = argv.indexOf(flag);
|
|
44
|
-
if (index < 0) return undefined;
|
|
45
|
-
const value = argv[index + 1];
|
|
46
|
-
return value === undefined || value.startsWith("-") ? undefined : value;
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const resolveInternalCommandAccess = async (
|
|
50
|
-
argv: readonly string[],
|
|
51
|
-
environment: TolokaEnvironment,
|
|
52
|
-
injectedClient: PotatoClient | undefined,
|
|
53
|
-
): Promise<boolean | undefined> => {
|
|
54
|
-
const commandName = commandNameFromArgv(argv);
|
|
55
|
-
if (
|
|
56
|
-
commandName !== "help" &&
|
|
57
|
-
commandName !== "project create" &&
|
|
58
|
-
!commandName.startsWith("delivery-order")
|
|
59
|
-
) {
|
|
60
|
-
return undefined;
|
|
61
|
-
}
|
|
62
|
-
if (injectedClient !== undefined) return resolveInternalUser(injectedClient);
|
|
63
|
-
try {
|
|
64
|
-
const apiKey = argvFlag(argv, "--api-key");
|
|
65
|
-
const baseUrl = argvFlag(argv, "--base-url");
|
|
66
|
-
const { found } = await findCommandCredentials(
|
|
67
|
-
environment,
|
|
68
|
-
apiKey ?? environment.TOLOKA_API_KEY,
|
|
69
|
-
);
|
|
70
|
-
const config = resolveTolokaConfig(
|
|
71
|
-
{
|
|
72
|
-
...(apiKey === undefined ? {} : { apiKey }),
|
|
73
|
-
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
74
|
-
},
|
|
75
|
-
undefined,
|
|
76
|
-
environment,
|
|
77
|
-
found?.credentials,
|
|
78
|
-
);
|
|
79
|
-
return await resolveInternalUser(
|
|
80
|
-
createClient({ apiKey: config.apiKey, baseUrl: config.baseUrl }),
|
|
81
|
-
);
|
|
82
|
-
} catch {
|
|
83
|
-
return undefined;
|
|
84
|
-
}
|
|
85
|
-
};
|
|
86
|
-
|
|
87
40
|
export function createProgram(context: ProgramContext): CreatedProgram {
|
|
88
41
|
const program = new Command("toloka");
|
|
89
42
|
const exitCode = { value: 0 };
|
|
@@ -91,7 +44,7 @@ export function createProgram(context: ProgramContext): CreatedProgram {
|
|
|
91
44
|
|
|
92
45
|
program
|
|
93
46
|
.description(
|
|
94
|
-
"
|
|
47
|
+
"Build and operate Toloka pipeline projects from TypeScript source. The public API may change between minor versions before 1.0.",
|
|
95
48
|
)
|
|
96
49
|
.version(SDK_VERSION, "-v, --version", "output the current version")
|
|
97
50
|
.option(
|
|
@@ -137,7 +90,7 @@ export function createProgram(context: ProgramContext): CreatedProgram {
|
|
|
137
90
|
registerConfigCommands(program, host);
|
|
138
91
|
registerAuthCommands(program, host);
|
|
139
92
|
registerProjectCommands(program, host);
|
|
140
|
-
|
|
93
|
+
registerDeliveryOrderCommands(program, host);
|
|
141
94
|
registerSourceCommands(program, host);
|
|
142
95
|
registerSecretCommands(program, host);
|
|
143
96
|
registerModelCommands(program, host);
|
|
@@ -263,11 +216,7 @@ export async function runTolokaCli(
|
|
|
263
216
|
...(injectedClient === undefined ? {} : { injectedClient }),
|
|
264
217
|
...(runChecks === undefined ? {} : { runChecks }),
|
|
265
218
|
};
|
|
266
|
-
const
|
|
267
|
-
const { program, exitCode } = createProgram({
|
|
268
|
-
...baseContext,
|
|
269
|
-
...(internalUser === undefined ? {} : { internalUser }),
|
|
270
|
-
});
|
|
219
|
+
const { program, exitCode } = createProgram(baseContext);
|
|
271
220
|
const startedAt = Date.now();
|
|
272
221
|
|
|
273
222
|
try {
|