trajectories-sh 1.11.0 → 1.13.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/dist/cli.js
CHANGED
|
@@ -76,12 +76,20 @@ async function uploadTrajectoryAction(directory, opts) {
|
|
|
76
76
|
console.error(chalk.red(" \u2717 Not authenticated. Run: trajectories auth login"));
|
|
77
77
|
process.exit(1);
|
|
78
78
|
}
|
|
79
|
+
if (opts.visibility === "public") {
|
|
80
|
+
console.error(
|
|
81
|
+
chalk.red(
|
|
82
|
+
" \u2717 --visibility public is not allowed from the CLI.\n Upload as 'unlisted' or 'private', then flip visibility to public\n from the trajectory page on trajectories.sh."
|
|
83
|
+
)
|
|
84
|
+
);
|
|
85
|
+
process.exit(1);
|
|
86
|
+
}
|
|
79
87
|
const slug = opts.slug ?? directory.replace(/\/+$/, "").split("/").pop();
|
|
80
88
|
console.log(chalk.bold(`
|
|
81
89
|
Uploading trajectory ${directory} \u2192 ${chalk.cyan(slug)}
|
|
82
90
|
`));
|
|
83
91
|
try {
|
|
84
|
-
const { uploadJob } = await import("./upload-
|
|
92
|
+
const { uploadJob } = await import("./upload-CDNIKYW3.js");
|
|
85
93
|
const result = await uploadJob(directory, {
|
|
86
94
|
slug,
|
|
87
95
|
name: opts.name,
|
|
@@ -92,8 +100,11 @@ async function uploadTrajectoryAction(directory, opts) {
|
|
|
92
100
|
if (result.meanReward != null) {
|
|
93
101
|
console.log(` Pass rate: ${(result.meanReward * 100).toFixed(0)}%`);
|
|
94
102
|
}
|
|
95
|
-
console.log(` Viewer:
|
|
96
|
-
|
|
103
|
+
console.log(` Viewer: ${result.viewerUrl}`);
|
|
104
|
+
if (result.existingDuplicateUrl) {
|
|
105
|
+
console.log(` Earlier copy: ${result.existingDuplicateUrl}`);
|
|
106
|
+
}
|
|
107
|
+
console.log("");
|
|
97
108
|
} catch (e) {
|
|
98
109
|
console.error(chalk.red(`
|
|
99
110
|
\u2717 ${e.message}
|
|
@@ -219,7 +230,11 @@ async function deleteTrajectoryAction(url, opts) {
|
|
|
219
230
|
}
|
|
220
231
|
}
|
|
221
232
|
var upload = program.command("upload").description("Upload trajectories or tasks");
|
|
222
|
-
upload.command("trajectory <directory>").description("Upload a trajectory job directory").option("-s, --slug <slug>", "URL slug (default: directory name)").option("-n, --name <name>", "Display name (default: slug)").option(
|
|
233
|
+
upload.command("trajectory <directory>").description("Upload a trajectory job directory").option("-s, --slug <slug>", "URL slug (default: directory name)").option("-n, --name <name>", "Display name (default: slug)").option(
|
|
234
|
+
"-v, --visibility <vis>",
|
|
235
|
+
"unlisted or private (use the UI to flip a trajectory to public after upload)",
|
|
236
|
+
"private"
|
|
237
|
+
).action(uploadTrajectoryAction);
|
|
223
238
|
upload.command("task <directory>").description("Upload a benchmark task directory").option("-n, --name <name>", "Task name (default: directory name)").option("-v, --visibility <vis>", "public or private", "public").action(uploadTaskAction);
|
|
224
239
|
var download = program.command("download").description("Download trajectories");
|
|
225
240
|
download.command("trajectory <url>").description("Download a trajectory job from trajectories.sh").option("-o, --output <dir>", "Output directory (default: slug name)").action(downloadTrajectoryAction);
|
|
@@ -345,14 +345,18 @@ async function uploadJob(dir, opts) {
|
|
|
345
345
|
}
|
|
346
346
|
const initResp = await apiPost("/api/cli/push/init", { slug, name, visibility, estimated_bytes: totalSize, content_hash: contentHash });
|
|
347
347
|
if (!initResp.ok) {
|
|
348
|
-
if (initResp.status === 409) {
|
|
349
|
-
const err = await initResp.json().catch(() => ({ detail: "Duplicate trajectory" }));
|
|
350
|
-
throw new Error(err.detail);
|
|
351
|
-
}
|
|
352
348
|
throw new Error(`Init failed: ${await initResp.text()}`);
|
|
353
349
|
}
|
|
354
|
-
const
|
|
350
|
+
const initBody = await initResp.json();
|
|
351
|
+
const jobId = initBody.job_id;
|
|
355
352
|
console.log(` Job ID: ${jobId}`);
|
|
353
|
+
const apiUrlEarly = getApiUrl();
|
|
354
|
+
const siteUrlEarly = apiUrlEarly.includes("localhost") ? "http://localhost:3000" : apiUrlEarly.replace("api.", "").replace(/\/$/, "");
|
|
355
|
+
const existingDuplicateUrl = initBody.existing_duplicate ? `${siteUrlEarly}/t/${initBody.existing_duplicate.job_id}` : void 0;
|
|
356
|
+
if (existingDuplicateUrl) {
|
|
357
|
+
console.log(` \u24D8 This content was already uploaded as '${initBody.existing_duplicate.slug}' \u2014 uploading anyway.`);
|
|
358
|
+
console.log(` Existing: ${existingDuplicateUrl}`);
|
|
359
|
+
}
|
|
356
360
|
await uploadDirect(jobId, files);
|
|
357
361
|
console.log(" Finalizing...");
|
|
358
362
|
const finalResp = await apiPost(`/api/cli/push/${jobId}/finalize`, {});
|
|
@@ -381,7 +385,8 @@ async function uploadJob(dir, opts) {
|
|
|
381
385
|
slug: result.slug,
|
|
382
386
|
nTrials: result.n_trials,
|
|
383
387
|
meanReward: result.mean_reward,
|
|
384
|
-
viewerUrl: `${siteUrl}/t/${jobId}
|
|
388
|
+
viewerUrl: `${siteUrl}/t/${jobId}`,
|
|
389
|
+
existingDuplicateUrl
|
|
385
390
|
};
|
|
386
391
|
}
|
|
387
392
|
async function uploadDirect(jobId, files) {
|