@wavespeed/cli 0.2.1 → 0.2.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.
- package/README.md +4 -2
- package/dist/commands/run.js +43 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -35,8 +35,9 @@
|
|
|
35
35
|
# npm
|
|
36
36
|
npm install -g @wavespeed/cli
|
|
37
37
|
|
|
38
|
-
# or curl
|
|
39
|
-
|
|
38
|
+
# or curl (script lives on GitHub; wraps `npm install -g` with a
|
|
39
|
+
# friendlier error path)
|
|
40
|
+
curl -fsSL https://raw.githubusercontent.com/WaveSpeedAI/wavespeed-cli/main/install.sh | bash
|
|
40
41
|
|
|
41
42
|
# sign in (opens the access-key page, paste to confirm)
|
|
42
43
|
wavespeed login
|
|
@@ -123,6 +124,7 @@ wavespeed config [--default-model …] View / update CLI defaults
|
|
|
123
124
|
|
|
124
125
|
# generation
|
|
125
126
|
wavespeed run [model|alias] -p "…" Run any model or alias (uses defaultModel if omitted)
|
|
127
|
+
wavespeed run <model|alias> --sync Attempt sync wait; timed-out tasks remain queryable
|
|
126
128
|
wavespeed run <model|alias> -h Dynamic schema-based help (alias-aware)
|
|
127
129
|
wavespeed schema <model> Pretty-print a model's input schema
|
|
128
130
|
wavespeed models [query] Browse the live catalog (cached 1h)
|
package/dist/commands/run.js
CHANGED
|
@@ -18,6 +18,20 @@ function extractUrls(output) {
|
|
|
18
18
|
return [output.url];
|
|
19
19
|
return [];
|
|
20
20
|
}
|
|
21
|
+
function cleanTrailingPunctuation(value) {
|
|
22
|
+
return value.replace(/[).,]+$/, '');
|
|
23
|
+
}
|
|
24
|
+
function extractSyncTimeoutDetails(message) {
|
|
25
|
+
if (!message.includes('Sync mode timed out'))
|
|
26
|
+
return null;
|
|
27
|
+
const taskIdMatch = message.match(/task_id:\s*([^)]+)/) ??
|
|
28
|
+
message.match(/Prediction ID:\s*([^\s.]+)/);
|
|
29
|
+
const resultUrlMatch = message.match(/Query the result later at:\s*(\S+)/);
|
|
30
|
+
return {
|
|
31
|
+
predictionId: taskIdMatch?.[1] ? cleanTrailingPunctuation(taskIdMatch[1]) : undefined,
|
|
32
|
+
resultUrl: resultUrlMatch?.[1] ? cleanTrailingPunctuation(resultUrlMatch[1]) : undefined,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
21
35
|
function failMissingModel() {
|
|
22
36
|
const msg = 'No model specified. Pass a model ID as the first argument, ' +
|
|
23
37
|
'set `defaultModel` in wavespeed.json, or `wavespeed config --default-model <id>`.';
|
|
@@ -49,7 +63,7 @@ export function registerRun(program) {
|
|
|
49
63
|
.option('-p, --prompt <text>', 'Shorthand for --input prompt=<text>')
|
|
50
64
|
.option('--input-file <path>', 'JSON file with full input object')
|
|
51
65
|
.option('--download [path]', 'Save outputs locally (optional path template, e.g. "./out/{index}.{ext}")')
|
|
52
|
-
.option('--sync', '
|
|
66
|
+
.option('--sync', 'Attempt sync mode; timed-out tasks can still be queried later')
|
|
53
67
|
.option('--json', 'Emit a single JSON object on stdout (progress goes to stderr)')
|
|
54
68
|
.option('--output-dir <dir>', 'Directory for --download when no path is given')
|
|
55
69
|
.action(async (modelArg, opts) => {
|
|
@@ -98,9 +112,34 @@ export function registerRun(program) {
|
|
|
98
112
|
spinner.succeed(`Done in ${Math.floor((Date.now() - startedAt) / 1000)}s.`);
|
|
99
113
|
}
|
|
100
114
|
catch (err) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
115
|
+
const message = err.message ?? String(err);
|
|
116
|
+
const syncTimeout = opts.sync ? extractSyncTimeoutDetails(message) : null;
|
|
117
|
+
if (syncTimeout && !isJsonMode()) {
|
|
118
|
+
spinner.fail('Sync mode timed out; the task is still processing asynchronously.');
|
|
119
|
+
log(chalk.gray(' reason: ') + message);
|
|
120
|
+
if (syncTimeout.predictionId) {
|
|
121
|
+
log(chalk.gray(' prediction: ') + chalk.white(syncTimeout.predictionId));
|
|
122
|
+
log(chalk.gray(' query: ') + chalk.cyan(`wavespeed show ${syncTimeout.predictionId}`));
|
|
123
|
+
}
|
|
124
|
+
if (syncTimeout.resultUrl) {
|
|
125
|
+
log(chalk.gray(' result URL: ') + chalk.cyan(syncTimeout.resultUrl));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
spinner.fail(message);
|
|
130
|
+
}
|
|
131
|
+
if (isJsonMode()) {
|
|
132
|
+
emitJsonError(message, syncTimeout
|
|
133
|
+
? {
|
|
134
|
+
sync_timeout: true,
|
|
135
|
+
prediction_id: syncTimeout.predictionId,
|
|
136
|
+
result_url: syncTimeout.resultUrl,
|
|
137
|
+
query_command: syncTimeout.predictionId
|
|
138
|
+
? `wavespeed show ${syncTimeout.predictionId}`
|
|
139
|
+
: undefined,
|
|
140
|
+
}
|
|
141
|
+
: {});
|
|
142
|
+
}
|
|
104
143
|
process.exit(1);
|
|
105
144
|
}
|
|
106
145
|
const urls = extractUrls(result);
|