trajectories-sh 1.12.0 → 1.14.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-DKXZOGUF.js");
|
|
85
93
|
const result = await uploadJob(directory, {
|
|
86
94
|
slug,
|
|
87
95
|
name: opts.name,
|
|
@@ -222,7 +230,11 @@ async function deleteTrajectoryAction(url, opts) {
|
|
|
222
230
|
}
|
|
223
231
|
}
|
|
224
232
|
var upload = program.command("upload").description("Upload trajectories or tasks");
|
|
225
|
-
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);
|
|
226
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);
|
|
227
239
|
var download = program.command("download").description("Download trajectories");
|
|
228
240
|
download.command("trajectory <url>").description("Download a trajectory job from trajectories.sh").option("-o, --output <dir>", "Output directory (default: slug name)").action(downloadTrajectoryAction);
|
|
@@ -403,14 +403,15 @@ async function uploadDirect(jobId, files) {
|
|
|
403
403
|
const pending = /* @__PURE__ */ new Set();
|
|
404
404
|
for (let bi = 0; bi < batches.length; bi++) {
|
|
405
405
|
const batch = batches[bi];
|
|
406
|
-
const urlMap = await nextUrlsPromise;
|
|
406
|
+
const { urlMap, errors: urlErrors } = await nextUrlsPromise;
|
|
407
407
|
nextUrlsPromise = bi + 1 < batches.length ? fetchSignedUrlsForBatch(jobId, batches[bi + 1].map((f) => f.relPath)) : null;
|
|
408
408
|
for (const file of batch) {
|
|
409
409
|
if (!urlMap.has(file.relPath)) {
|
|
410
410
|
failedFiles.push(file.relPath);
|
|
411
|
+
const serverError = urlErrors.get(file.relPath);
|
|
411
412
|
failureReasons.push({
|
|
412
413
|
path: file.relPath,
|
|
413
|
-
reason: "no signed URL from server after retries"
|
|
414
|
+
reason: serverError ? `signed-url error: ${truncate(serverError, 140)}` : "no signed URL from server after retries"
|
|
414
415
|
});
|
|
415
416
|
bar.tick(0);
|
|
416
417
|
continue;
|
|
@@ -438,21 +439,31 @@ async function uploadDirect(jobId, files) {
|
|
|
438
439
|
bar.done();
|
|
439
440
|
if (failedFiles.length > 0) {
|
|
440
441
|
const byReason = /* @__PURE__ */ new Map();
|
|
441
|
-
for (const { reason } of failureReasons) {
|
|
442
|
-
|
|
442
|
+
for (const { reason, path } of failureReasons) {
|
|
443
|
+
const existing = byReason.get(reason);
|
|
444
|
+
if (existing) {
|
|
445
|
+
existing.count++;
|
|
446
|
+
} else {
|
|
447
|
+
byReason.set(reason, { count: 1, samplePath: path });
|
|
448
|
+
}
|
|
443
449
|
}
|
|
444
|
-
const reasonLines = [...byReason.entries()].sort((a, b) => b[1] - a[1]).map(([reason, count]) => ` ${count}\xD7 ${reason}
|
|
445
|
-
|
|
450
|
+
const reasonLines = [...byReason.entries()].sort((a, b) => b[1].count - a[1].count).map(([reason, { count, samplePath }]) => ` ${count}\xD7 ${reason}
|
|
451
|
+
e.g. ${samplePath}`).join("\n");
|
|
446
452
|
throw new Error(
|
|
447
|
-
`Upload incomplete: ${failedFiles.length}/${files.length} file(s) failed.
|
|
453
|
+
`Upload incomplete: ${failedFiles.length}/${files.length} file(s) failed.
|
|
448
454
|
Failure breakdown:
|
|
449
455
|
${reasonLines}
|
|
450
|
-
|
|
456
|
+
|
|
457
|
+
If these look like 409 / "already exists" errors, the previous upload
|
|
458
|
+
attempt left stale files at the same storage path. Retry the upload \u2014
|
|
459
|
+
the server now heals those on the next push_init. Otherwise retry
|
|
460
|
+
after a minute or check https://status.supabase.com.`
|
|
451
461
|
);
|
|
452
462
|
}
|
|
453
463
|
}
|
|
454
464
|
async function fetchSignedUrlsForBatch(jobId, paths) {
|
|
455
465
|
const urlMap = /* @__PURE__ */ new Map();
|
|
466
|
+
const errors = /* @__PURE__ */ new Map();
|
|
456
467
|
let pending = paths.slice();
|
|
457
468
|
const attempts = 4;
|
|
458
469
|
for (let attempt = 0; attempt < attempts && pending.length > 0; attempt++) {
|
|
@@ -471,13 +482,15 @@ async function fetchSignedUrlsForBatch(jobId, paths) {
|
|
|
471
482
|
for (const u of urls) {
|
|
472
483
|
if (u.signed_url) {
|
|
473
484
|
urlMap.set(u.path, u.signed_url);
|
|
485
|
+
errors.delete(u.path);
|
|
474
486
|
} else {
|
|
487
|
+
if (u.error) errors.set(u.path, u.error);
|
|
475
488
|
stillPending.push(u.path);
|
|
476
489
|
}
|
|
477
490
|
}
|
|
478
491
|
pending = stillPending;
|
|
479
492
|
}
|
|
480
|
-
return urlMap;
|
|
493
|
+
return { urlMap, errors };
|
|
481
494
|
}
|
|
482
495
|
async function uploadOneFileWithError(file, signedUrl) {
|
|
483
496
|
const data = readFileSync(file.absPath);
|
|
@@ -507,6 +520,9 @@ async function uploadOneFileWithError(file, signedUrl) {
|
|
|
507
520
|
function sleep(ms) {
|
|
508
521
|
return new Promise((r) => setTimeout(r, ms));
|
|
509
522
|
}
|
|
523
|
+
function truncate(s, n) {
|
|
524
|
+
return s.length > n ? s.slice(0, n - 1) + "\u2026" : s;
|
|
525
|
+
}
|
|
510
526
|
export {
|
|
511
527
|
collectFiles,
|
|
512
528
|
uploadJob
|