jimeng-cli 0.3.0 → 0.3.2
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 +1 -1
- package/dist/{chunk-2IIK4X7C.js → chunk-FAXTAAQO.js} +90 -45
- package/dist/{chunk-2IIK4X7C.js.map → chunk-FAXTAAQO.js.map} +1 -1
- package/dist/cli/index.cjs +366 -283
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +277 -240
- package/dist/cli/index.js.map +1 -1
- package/dist/mcp/index.cjs +93 -48
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.js +6 -5
- package/dist/mcp/index.js.map +1 -1
- package/package.json +4 -4
package/dist/cli/index.js
CHANGED
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
session_pool_default,
|
|
18
18
|
upscaleImage,
|
|
19
19
|
waitForTaskResponse
|
|
20
|
-
} from "../chunk-
|
|
20
|
+
} from "../chunk-FAXTAAQO.js";
|
|
21
21
|
|
|
22
22
|
// src/cli/app.ts
|
|
23
23
|
import process2 from "process";
|
|
@@ -28,8 +28,7 @@ import path from "path";
|
|
|
28
28
|
import { access, readFile } from "fs/promises";
|
|
29
29
|
import minimist from "minimist";
|
|
30
30
|
function maskToken(token) {
|
|
31
|
-
|
|
32
|
-
if (n <= 10) return "***";
|
|
31
|
+
if (token.length <= 10) return "***";
|
|
33
32
|
return `${token.slice(0, 4)}...${token.slice(-4)}`;
|
|
34
33
|
}
|
|
35
34
|
function formatUnixMs(value) {
|
|
@@ -44,14 +43,14 @@ function printTokenEntriesTable(items) {
|
|
|
44
43
|
console.log("token region enabled live lastCredit lastCheckedAt failures");
|
|
45
44
|
for (const item of items) {
|
|
46
45
|
if (!item || typeof item !== "object") continue;
|
|
47
|
-
const
|
|
48
|
-
const token = typeof
|
|
49
|
-
const region = typeof
|
|
50
|
-
const enabled = typeof
|
|
51
|
-
const live = typeof
|
|
52
|
-
const lastCredit = typeof
|
|
53
|
-
const lastCheckedAt = formatUnixMs(
|
|
54
|
-
const failures = typeof
|
|
46
|
+
const e = item;
|
|
47
|
+
const token = typeof e.token === "string" ? e.token : "-";
|
|
48
|
+
const region = typeof e.region === "string" ? e.region : "-";
|
|
49
|
+
const enabled = typeof e.enabled === "boolean" ? String(e.enabled) : "-";
|
|
50
|
+
const live = typeof e.live === "boolean" ? String(e.live) : "-";
|
|
51
|
+
const lastCredit = typeof e.lastCredit === "number" ? String(e.lastCredit) : "-";
|
|
52
|
+
const lastCheckedAt = formatUnixMs(e.lastCheckedAt);
|
|
53
|
+
const failures = typeof e.consecutiveFailures === "number" ? String(e.consecutiveFailures) : "-";
|
|
55
54
|
console.log(`${token} ${region} ${enabled} ${live} ${lastCredit} ${lastCheckedAt} ${failures}`);
|
|
56
55
|
}
|
|
57
56
|
}
|
|
@@ -90,6 +89,30 @@ ${usage}`);
|
|
|
90
89
|
}
|
|
91
90
|
return deduped;
|
|
92
91
|
}
|
|
92
|
+
function resolveTokenRegionPairs(explicitTokens, regionCode, deps, opts) {
|
|
93
|
+
if (explicitTokens.length > 0) {
|
|
94
|
+
return explicitTokens.map((token) => {
|
|
95
|
+
var _a;
|
|
96
|
+
const entryRegion = (_a = session_pool_default.getTokenEntry(token)) == null ? void 0 : _a.region;
|
|
97
|
+
const finalRegion = regionCode || entryRegion;
|
|
98
|
+
if (!finalRegion) {
|
|
99
|
+
deps.fail(`Missing region for token ${maskToken(token)}. Provide --region or register token in token-pool.`);
|
|
100
|
+
}
|
|
101
|
+
return { token, region: finalRegion };
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const requireLive = (opts == null ? void 0 : opts.requireLive) ?? true;
|
|
105
|
+
const entries = session_pool_default.getEntries(false).filter((item) => {
|
|
106
|
+
if (!item.enabled || !item.region) return false;
|
|
107
|
+
if (requireLive && item.live === false) return false;
|
|
108
|
+
if (regionCode && item.region !== regionCode) return false;
|
|
109
|
+
return true;
|
|
110
|
+
});
|
|
111
|
+
if (entries.length === 0) {
|
|
112
|
+
deps.fail("No token available. Provide --token or configure token-pool.");
|
|
113
|
+
}
|
|
114
|
+
return entries.map((item) => ({ token: item.token, region: item.region }));
|
|
115
|
+
}
|
|
93
116
|
function createTokenSubcommands(deps) {
|
|
94
117
|
const handleTokenCheck = async (argv) => {
|
|
95
118
|
const args = minimist(argv, {
|
|
@@ -101,74 +124,68 @@ function createTokenSubcommands(deps) {
|
|
|
101
124
|
console.log(usage);
|
|
102
125
|
return;
|
|
103
126
|
}
|
|
104
|
-
const
|
|
105
|
-
const regionCode = deps.parseRegionOrFail(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
const tokens = await collectTokensFromArgs(args, usage, deps, true);
|
|
127
|
+
const explicitRegion = deps.getSingleString(args, "region");
|
|
128
|
+
const regionCode = explicitRegion ? deps.parseRegionOrFail(explicitRegion) : void 0;
|
|
129
|
+
await deps.ensureTokenPoolReady();
|
|
130
|
+
const explicitTokens = await collectTokensFromArgs(args, usage, deps, false);
|
|
131
|
+
const pairs = resolveTokenRegionPairs(explicitTokens, regionCode, deps, { requireLive: false });
|
|
110
132
|
if (!args.json) {
|
|
111
|
-
console.log(`Checking ${
|
|
133
|
+
console.log(`Checking ${pairs.length} token(s)`);
|
|
112
134
|
}
|
|
113
|
-
await deps.ensureTokenPoolReady();
|
|
114
135
|
let invalid = 0;
|
|
115
136
|
let requestErrors = 0;
|
|
116
137
|
const results = [];
|
|
117
|
-
for (const token of
|
|
138
|
+
for (const { token, region } of pairs) {
|
|
118
139
|
const masked = maskToken(token);
|
|
119
140
|
try {
|
|
120
|
-
const live = await getTokenLiveStatus(token, buildRegionInfo(
|
|
141
|
+
const live = await getTokenLiveStatus(token, buildRegionInfo(region));
|
|
121
142
|
await session_pool_default.syncTokenCheckResult(token, live);
|
|
122
|
-
if (live
|
|
123
|
-
if (!args.json) console.log(`[OK] ${masked} live=true`);
|
|
143
|
+
if (live) {
|
|
144
|
+
if (!args.json) console.log(`[OK] ${masked} (${region}) live=true`);
|
|
145
|
+
results.push({ token_masked: masked, region, live: true });
|
|
124
146
|
} else {
|
|
125
147
|
invalid += 1;
|
|
126
|
-
if (!args.json) console.log(`[FAIL] ${masked} live=false`);
|
|
148
|
+
if (!args.json) console.log(`[FAIL] ${masked} (${region}) live=false`);
|
|
149
|
+
results.push({ token_masked: masked, region, live: false });
|
|
127
150
|
}
|
|
128
|
-
results.push({ token_masked: masked, live: live === true });
|
|
129
151
|
} catch (error) {
|
|
130
152
|
requestErrors += 1;
|
|
131
153
|
const message = error instanceof Error ? error.message : String(error);
|
|
132
|
-
if (!args.json) console.log(`[ERROR] ${masked} ${message}`);
|
|
133
|
-
results.push({ token_masked: masked, error: message });
|
|
154
|
+
if (!args.json) console.log(`[ERROR] ${masked} (${region}) ${message}`);
|
|
155
|
+
results.push({ token_masked: masked, region, error: message });
|
|
134
156
|
}
|
|
135
157
|
}
|
|
136
158
|
if (args.json) {
|
|
137
159
|
deps.printCommandJson("token.check", results, {
|
|
138
|
-
total:
|
|
160
|
+
total: pairs.length,
|
|
139
161
|
invalid,
|
|
140
162
|
request_errors: requestErrors
|
|
141
163
|
});
|
|
142
164
|
} else {
|
|
143
|
-
console.log(`Summary: total=${
|
|
165
|
+
console.log(`Summary: total=${pairs.length} invalid=${invalid} request_errors=${requestErrors}`);
|
|
144
166
|
}
|
|
145
167
|
if (requestErrors > 0) process.exit(3);
|
|
146
168
|
if (invalid > 0) process.exit(2);
|
|
147
169
|
};
|
|
148
170
|
const handleTokenList = async (argv) => {
|
|
149
|
-
const args = minimist(argv, {
|
|
150
|
-
boolean: ["help", "json"]
|
|
151
|
-
});
|
|
152
|
-
const usage = deps.getUsage("list");
|
|
171
|
+
const args = minimist(argv, { boolean: ["help", "json"] });
|
|
153
172
|
if (args.help) {
|
|
154
|
-
console.log(
|
|
173
|
+
console.log(deps.getUsage("list"));
|
|
155
174
|
return;
|
|
156
175
|
}
|
|
157
176
|
await deps.ensureTokenPoolReady();
|
|
158
|
-
const
|
|
177
|
+
const snapshot = buildTokenPoolSnapshot();
|
|
159
178
|
if (args.json) {
|
|
160
|
-
deps.printCommandJson("token.list",
|
|
179
|
+
deps.printCommandJson("token.list", snapshot);
|
|
161
180
|
return;
|
|
162
181
|
}
|
|
163
|
-
const body =
|
|
164
|
-
|
|
165
|
-
if (summary && typeof summary === "object") {
|
|
182
|
+
const body = snapshot && typeof snapshot === "object" ? snapshot : {};
|
|
183
|
+
if (body.summary && typeof body.summary === "object") {
|
|
166
184
|
console.log("Summary:");
|
|
167
|
-
deps.printJson(summary);
|
|
185
|
+
deps.printJson(body.summary);
|
|
168
186
|
}
|
|
169
|
-
const items = Array.isArray(body.items) ? body.items : [];
|
|
170
187
|
console.log("Entries:");
|
|
171
|
-
printTokenEntriesTable(items);
|
|
188
|
+
printTokenEntriesTable(Array.isArray(body.items) ? body.items : []);
|
|
172
189
|
};
|
|
173
190
|
const handleTokenPointsOrReceive = async (argv, action) => {
|
|
174
191
|
const args = minimist(argv, {
|
|
@@ -180,45 +197,30 @@ function createTokenSubcommands(deps) {
|
|
|
180
197
|
console.log(usage);
|
|
181
198
|
return;
|
|
182
199
|
}
|
|
183
|
-
const
|
|
184
|
-
const regionCode = deps.parseRegionOrFail(
|
|
200
|
+
const regionArg = deps.getSingleString(args, "region");
|
|
201
|
+
const regionCode = regionArg ? deps.parseRegionOrFail(regionArg) : void 0;
|
|
185
202
|
await deps.ensureTokenPoolReady();
|
|
186
|
-
const
|
|
187
|
-
const
|
|
188
|
-
var _a;
|
|
189
|
-
const entryRegion = (_a = session_pool_default.getTokenEntry(token)) == null ? void 0 : _a.region;
|
|
190
|
-
const finalRegion = regionCode || entryRegion;
|
|
191
|
-
if (!finalRegion) {
|
|
192
|
-
deps.fail(`Missing region for token ${maskToken(token)}. Provide --region or register token region in token-pool.`);
|
|
193
|
-
}
|
|
194
|
-
return { token, region: finalRegion };
|
|
195
|
-
}) : session_pool_default.getEntries(false).filter((item) => item.enabled && item.live !== false && item.region).filter((item) => regionCode ? item.region === regionCode : true).map((item) => ({ token: item.token, region: item.region }));
|
|
196
|
-
if (resolvedTokens.length === 0) {
|
|
197
|
-
deps.fail("No token available. Provide --token or configure token-pool.");
|
|
198
|
-
}
|
|
203
|
+
const explicitTokens = await collectTokensFromArgs(args, usage, deps, false);
|
|
204
|
+
const pairs = resolveTokenRegionPairs(explicitTokens, regionCode, deps);
|
|
199
205
|
const payload = action === "points" ? await Promise.all(
|
|
200
|
-
|
|
201
|
-
token
|
|
202
|
-
points: await getCredit(
|
|
206
|
+
pairs.map(async ({ token, region }) => ({
|
|
207
|
+
token,
|
|
208
|
+
points: await getCredit(token, buildRegionInfo(region))
|
|
203
209
|
}))
|
|
204
210
|
) : await Promise.all(
|
|
205
|
-
|
|
206
|
-
const
|
|
211
|
+
pairs.map(async ({ token, region }) => {
|
|
212
|
+
const regionInfo = buildRegionInfo(region);
|
|
213
|
+
const currentCredit = await getCredit(token, regionInfo);
|
|
207
214
|
if (currentCredit.totalCredit <= 0) {
|
|
208
215
|
try {
|
|
209
|
-
await receiveCredit(
|
|
210
|
-
const updatedCredit = await getCredit(
|
|
211
|
-
return { token
|
|
216
|
+
await receiveCredit(token, regionInfo);
|
|
217
|
+
const updatedCredit = await getCredit(token, regionInfo);
|
|
218
|
+
return { token, credits: updatedCredit, received: true };
|
|
212
219
|
} catch (error) {
|
|
213
|
-
return {
|
|
214
|
-
token: item.token,
|
|
215
|
-
credits: currentCredit,
|
|
216
|
-
received: false,
|
|
217
|
-
error: (error == null ? void 0 : error.message) || String(error)
|
|
218
|
-
};
|
|
220
|
+
return { token, credits: currentCredit, received: false, error: (error == null ? void 0 : error.message) || String(error) };
|
|
219
221
|
}
|
|
220
222
|
}
|
|
221
|
-
return { token
|
|
223
|
+
return { token, credits: currentCredit, received: false };
|
|
222
224
|
})
|
|
223
225
|
);
|
|
224
226
|
if (args.json) {
|
|
@@ -237,28 +239,32 @@ function createTokenSubcommands(deps) {
|
|
|
237
239
|
console.log(usage);
|
|
238
240
|
return;
|
|
239
241
|
}
|
|
240
|
-
const region = deps.getRegionWithDefault(args);
|
|
241
242
|
await deps.ensureTokenPoolReady();
|
|
242
243
|
const tokens = await collectTokensFromArgs(args, usage, deps, true);
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
244
|
+
let payload;
|
|
245
|
+
let jsonMeta;
|
|
246
|
+
if (action === "add") {
|
|
247
|
+
const region = deps.getRegionWithDefault(args);
|
|
248
|
+
const regionCode = deps.parseRegionOrFail(region);
|
|
249
|
+
payload = {
|
|
250
|
+
...await session_pool_default.addTokens(tokens, { defaultRegion: regionCode || void 0 }),
|
|
251
|
+
summary: session_pool_default.getSummary()
|
|
252
|
+
};
|
|
253
|
+
jsonMeta = { region };
|
|
254
|
+
} else {
|
|
255
|
+
payload = {
|
|
256
|
+
...await session_pool_default.removeTokens(tokens),
|
|
257
|
+
summary: session_pool_default.getSummary()
|
|
258
|
+
};
|
|
259
|
+
}
|
|
251
260
|
if (args.json) {
|
|
252
|
-
deps.printCommandJson(`token.${action}`, deps.unwrapBody(payload),
|
|
261
|
+
deps.printCommandJson(`token.${action}`, deps.unwrapBody(payload), jsonMeta);
|
|
253
262
|
return;
|
|
254
263
|
}
|
|
255
264
|
deps.printJson(deps.unwrapBody(payload));
|
|
256
265
|
};
|
|
257
266
|
const handleTokenEnableOrDisable = async (argv, action) => {
|
|
258
|
-
const args = minimist(argv, {
|
|
259
|
-
string: ["token"],
|
|
260
|
-
boolean: ["help", "json"]
|
|
261
|
-
});
|
|
267
|
+
const args = minimist(argv, { string: ["token"], boolean: ["help", "json"] });
|
|
262
268
|
const usage = deps.getUsage(action);
|
|
263
269
|
if (args.help) {
|
|
264
270
|
console.log(usage);
|
|
@@ -280,44 +286,34 @@ function createTokenSubcommands(deps) {
|
|
|
280
286
|
deps.printJson(deps.unwrapBody(payload));
|
|
281
287
|
};
|
|
282
288
|
const handleTokenPool = async (argv) => {
|
|
283
|
-
const args = minimist(argv, {
|
|
284
|
-
boolean: ["help", "json"]
|
|
285
|
-
});
|
|
286
|
-
const usage = deps.getUsage("pool");
|
|
289
|
+
const args = minimist(argv, { boolean: ["help", "json"] });
|
|
287
290
|
if (args.help) {
|
|
288
|
-
console.log(
|
|
291
|
+
console.log(deps.getUsage("pool"));
|
|
289
292
|
return;
|
|
290
293
|
}
|
|
291
294
|
await deps.ensureTokenPoolReady();
|
|
292
|
-
const
|
|
295
|
+
const snapshot = buildTokenPoolSnapshot();
|
|
293
296
|
if (args.json) {
|
|
294
|
-
deps.printCommandJson("token.pool",
|
|
297
|
+
deps.printCommandJson("token.pool", snapshot);
|
|
295
298
|
return;
|
|
296
299
|
}
|
|
297
|
-
const body =
|
|
300
|
+
const body = snapshot && typeof snapshot === "object" ? snapshot : {};
|
|
298
301
|
console.log("Summary:");
|
|
299
302
|
deps.printJson(body.summary ?? {});
|
|
300
303
|
console.log("Entries:");
|
|
301
304
|
printTokenEntriesTable(Array.isArray(body.items) ? body.items : []);
|
|
302
305
|
};
|
|
303
306
|
const handleTokenPoolCheckOrReload = async (argv, action) => {
|
|
304
|
-
const args = minimist(argv, {
|
|
305
|
-
boolean: ["help", "json"]
|
|
306
|
-
});
|
|
307
|
-
const usage = deps.getUsage(action);
|
|
307
|
+
const args = minimist(argv, { boolean: ["help", "json"] });
|
|
308
308
|
if (args.help) {
|
|
309
|
-
console.log(
|
|
309
|
+
console.log(deps.getUsage(action));
|
|
310
310
|
return;
|
|
311
311
|
}
|
|
312
312
|
await deps.ensureTokenPoolReady();
|
|
313
|
-
const payload = action === "pool-check" ? {
|
|
314
|
-
|
|
315
|
-
summary: session_pool_default.getSummary()
|
|
316
|
-
}
|
|
317
|
-
reloaded: true,
|
|
318
|
-
summary: session_pool_default.getSummary(),
|
|
319
|
-
items: buildTokenPoolSnapshot().items
|
|
320
|
-
});
|
|
313
|
+
const payload = action === "pool-check" ? { ...await session_pool_default.runHealthCheck(), summary: session_pool_default.getSummary() } : (() => {
|
|
314
|
+
session_pool_default.reloadFromDisk();
|
|
315
|
+
return { reloaded: true, summary: session_pool_default.getSummary(), items: buildTokenPoolSnapshot().items };
|
|
316
|
+
})();
|
|
321
317
|
if (args.json) {
|
|
322
318
|
deps.printCommandJson(`token.${action}`, deps.unwrapBody(payload));
|
|
323
319
|
return;
|
|
@@ -334,12 +330,12 @@ function createTokenSubcommands(deps) {
|
|
|
334
330
|
},
|
|
335
331
|
{
|
|
336
332
|
name: "check",
|
|
337
|
-
description: "Validate tokens
|
|
338
|
-
usageLine: " jimeng token check
|
|
333
|
+
description: "Validate tokens",
|
|
334
|
+
usageLine: " jimeng token check [options]",
|
|
339
335
|
options: [
|
|
340
|
-
" --token <token> Token, can be repeated",
|
|
336
|
+
" --token <token> Token, can be repeated (default: all enabled tokens)",
|
|
341
337
|
" --token-file <path> Read tokens from file (one per line, # for comments)",
|
|
342
|
-
" --region <region>
|
|
338
|
+
" --region <region> Override region (default: token's registered region)",
|
|
343
339
|
deps.jsonOption,
|
|
344
340
|
deps.helpOption
|
|
345
341
|
],
|
|
@@ -347,12 +343,12 @@ function createTokenSubcommands(deps) {
|
|
|
347
343
|
},
|
|
348
344
|
{
|
|
349
345
|
name: "points",
|
|
350
|
-
description: "Query token points
|
|
346
|
+
description: "Query token points",
|
|
351
347
|
usageLine: " jimeng token points [options]",
|
|
352
348
|
options: [
|
|
353
349
|
" --token <token> Token, can be repeated",
|
|
354
350
|
" --token-file <path> Read tokens from file (one per line, # for comments)",
|
|
355
|
-
" --region <region> Filter tokens by
|
|
351
|
+
" --region <region> Filter tokens by region (cn/us/hk/jp/sg)",
|
|
356
352
|
deps.jsonOption,
|
|
357
353
|
deps.helpOption
|
|
358
354
|
],
|
|
@@ -360,12 +356,12 @@ function createTokenSubcommands(deps) {
|
|
|
360
356
|
},
|
|
361
357
|
{
|
|
362
358
|
name: "receive",
|
|
363
|
-
description: "Receive token credits
|
|
359
|
+
description: "Receive token credits",
|
|
364
360
|
usageLine: " jimeng token receive [options]",
|
|
365
361
|
options: [
|
|
366
362
|
" --token <token> Token, can be repeated",
|
|
367
363
|
" --token-file <path> Read tokens from file (one per line, # for comments)",
|
|
368
|
-
" --region <region> Filter tokens by
|
|
364
|
+
" --region <region> Filter tokens by region (cn/us/hk/jp/sg)",
|
|
369
365
|
deps.jsonOption,
|
|
370
366
|
deps.helpOption
|
|
371
367
|
],
|
|
@@ -497,11 +493,62 @@ function printTaskInfo(task, deps) {
|
|
|
497
493
|
deps.printJson(task.data);
|
|
498
494
|
}
|
|
499
495
|
}
|
|
496
|
+
function outputTaskResult(command, normalized, isJson, deps) {
|
|
497
|
+
const taskInfo = collectTaskInfo(normalized, deps);
|
|
498
|
+
if (!taskInfo) {
|
|
499
|
+
const body = deps.unwrapBody(normalized);
|
|
500
|
+
if (isJson) deps.printCommandJson(command, body);
|
|
501
|
+
else deps.printJson(body);
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
if (isJson) deps.printCommandJson(command, taskInfo);
|
|
505
|
+
else printTaskInfo(taskInfo, deps);
|
|
506
|
+
}
|
|
507
|
+
function resolveSingleQueryToken(explicitToken, explicitRegion, deps) {
|
|
508
|
+
var _a;
|
|
509
|
+
const regionCode = explicitRegion ? deps.parseRegionOrFail(explicitRegion) : void 0;
|
|
510
|
+
if (explicitToken) {
|
|
511
|
+
const poolRegion = (_a = session_pool_default.getTokenEntry(explicitToken)) == null ? void 0 : _a.region;
|
|
512
|
+
const region = regionCode || poolRegion;
|
|
513
|
+
if (!region) {
|
|
514
|
+
deps.fail("Missing region for token. Provide --region or register token in token-pool.");
|
|
515
|
+
}
|
|
516
|
+
return { token: explicitToken, region };
|
|
517
|
+
}
|
|
518
|
+
if (!regionCode) {
|
|
519
|
+
const entry = session_pool_default.getEntries(false).find(
|
|
520
|
+
(item) => item.enabled && item.live !== false && item.region
|
|
521
|
+
);
|
|
522
|
+
if (!entry) {
|
|
523
|
+
deps.fail("No token available. Provide --token, --region, or --all.");
|
|
524
|
+
}
|
|
525
|
+
return { token: entry.token, region: entry.region };
|
|
526
|
+
}
|
|
527
|
+
return { token: void 0, region: regionCode };
|
|
528
|
+
}
|
|
529
|
+
function printModelIds(models) {
|
|
530
|
+
for (const item of models) {
|
|
531
|
+
if (!item || typeof item !== "object") continue;
|
|
532
|
+
const id = item.id;
|
|
533
|
+
if (typeof id === "string" && id.length > 0) console.log(id);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
function printModelVerbose(models) {
|
|
537
|
+
console.log("id type desc capabilities");
|
|
538
|
+
for (const item of models) {
|
|
539
|
+
if (!item || typeof item !== "object") continue;
|
|
540
|
+
const m = item;
|
|
541
|
+
const id = typeof m.id === "string" ? m.id : "";
|
|
542
|
+
if (!id) continue;
|
|
543
|
+
const type = typeof m.model_type === "string" ? m.model_type : "-";
|
|
544
|
+
const desc = typeof m.description === "string" ? m.description : "-";
|
|
545
|
+
const caps = Array.isArray(m.capabilities) ? m.capabilities.filter((c) => typeof c === "string").join(",") : "-";
|
|
546
|
+
console.log(`${id} type=${type} desc=${desc} capabilities=${caps}`);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
500
549
|
function createQueryCommandHandlers(deps) {
|
|
501
550
|
const handleModelsRefresh = async (argv) => {
|
|
502
|
-
const args = minimist2(argv, {
|
|
503
|
-
boolean: ["help", "json"]
|
|
504
|
-
});
|
|
551
|
+
const args = minimist2(argv, { boolean: ["help", "json"] });
|
|
505
552
|
if (args.help) {
|
|
506
553
|
console.log(deps.usageModelsRefresh());
|
|
507
554
|
return;
|
|
@@ -529,48 +576,68 @@ function createQueryCommandHandlers(deps) {
|
|
|
529
576
|
const handleModelsList = async (argv) => {
|
|
530
577
|
const args = minimist2(argv, {
|
|
531
578
|
string: ["region", "token"],
|
|
532
|
-
boolean: ["help", "json", "verbose"]
|
|
579
|
+
boolean: ["help", "json", "verbose", "all"]
|
|
533
580
|
});
|
|
534
581
|
if (args.help) {
|
|
535
582
|
console.log(deps.usageModelsList());
|
|
536
583
|
return;
|
|
537
584
|
}
|
|
538
|
-
const
|
|
539
|
-
const
|
|
540
|
-
const
|
|
585
|
+
const isJson = Boolean(args.json);
|
|
586
|
+
const isVerbose = Boolean(args.verbose);
|
|
587
|
+
const explicitRegion = deps.getSingleString(args, "region");
|
|
588
|
+
const explicitToken = deps.getSingleString(args, "token");
|
|
541
589
|
await deps.ensureTokenPoolReady();
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
590
|
+
if (args.all) {
|
|
591
|
+
const entries = session_pool_default.getEntries(false).filter(
|
|
592
|
+
(item) => item.enabled && item.live !== false && item.region
|
|
593
|
+
);
|
|
594
|
+
if (entries.length === 0) {
|
|
595
|
+
deps.fail("No enabled+live tokens with region found in pool.");
|
|
596
|
+
}
|
|
597
|
+
const results = [];
|
|
598
|
+
for (const entry of entries) {
|
|
599
|
+
const masked = entry.token.length <= 10 ? "***" : `${entry.token.slice(0, 4)}...${entry.token.slice(-4)}`;
|
|
600
|
+
try {
|
|
601
|
+
const direct2 = await getLiveModels(`Bearer ${entry.token}`, entry.region);
|
|
602
|
+
results.push({
|
|
603
|
+
token: masked,
|
|
604
|
+
region: entry.region,
|
|
605
|
+
models: direct2.data.map((m) => m.id)
|
|
606
|
+
});
|
|
607
|
+
} catch (error) {
|
|
608
|
+
results.push({ token: masked, region: entry.region, error: error.message });
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
if (isJson) {
|
|
612
|
+
deps.printCommandJson("models.list", results);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
for (const r of results) {
|
|
616
|
+
console.log(`[${r.region}] ${r.token}`);
|
|
617
|
+
if (r.error) {
|
|
618
|
+
console.log(` error: ${r.error}`);
|
|
619
|
+
} else {
|
|
620
|
+
for (const id of r.models) console.log(` ${id}`);
|
|
621
|
+
}
|
|
622
|
+
console.log("");
|
|
623
|
+
}
|
|
547
624
|
return;
|
|
548
625
|
}
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
const model = item;
|
|
558
|
-
const id = typeof model.id === "string" ? model.id : "";
|
|
559
|
-
if (!id) continue;
|
|
560
|
-
const modelType = typeof model.model_type === "string" ? model.model_type : "-";
|
|
561
|
-
const description = typeof model.description === "string" ? model.description : "-";
|
|
562
|
-
const capabilities = Array.isArray(model.capabilities) ? model.capabilities.filter((cap) => typeof cap === "string").join(",") : "-";
|
|
563
|
-
console.log(`${id} type=${modelType} desc=${description} capabilities=${capabilities}`);
|
|
564
|
-
}
|
|
626
|
+
const { token, region } = resolveSingleQueryToken(explicitToken, explicitRegion, deps);
|
|
627
|
+
const direct = await getLiveModels(token ? `Bearer ${token}` : void 0, region);
|
|
628
|
+
const models = direct.data;
|
|
629
|
+
if (isJson) {
|
|
630
|
+
deps.printCommandJson("models.list", { object: "list", data: models }, {
|
|
631
|
+
region: region || null,
|
|
632
|
+
token: token ? `${token.slice(0, 4)}...` : null
|
|
633
|
+
});
|
|
565
634
|
return;
|
|
566
635
|
}
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
const id = item.id;
|
|
570
|
-
if (typeof id === "string" && id.length > 0) {
|
|
571
|
-
console.log(id);
|
|
572
|
-
}
|
|
636
|
+
if (models.length === 0) {
|
|
637
|
+
deps.fail("No models found.");
|
|
573
638
|
}
|
|
639
|
+
if (isVerbose) printModelVerbose(models);
|
|
640
|
+
else printModelIds(models);
|
|
574
641
|
};
|
|
575
642
|
const handleTaskGet = async (argv) => {
|
|
576
643
|
const args = minimist2(argv, {
|
|
@@ -587,42 +654,13 @@ function createQueryCommandHandlers(deps) {
|
|
|
587
654
|
${deps.usageTaskGet()}`);
|
|
588
655
|
const type = parseTaskTypeOrFail(deps.getSingleString(args, "type"), deps);
|
|
589
656
|
const responseFormat = parseResponseFormatOrFail(deps.getSingleString(args, "response-format"), deps);
|
|
590
|
-
const
|
|
591
|
-
const
|
|
592
|
-
|
|
593
|
-
const pick = await deps.pickDirectTokenForTask(token, region);
|
|
594
|
-
const normalized = await getTaskResponse(
|
|
595
|
-
taskId,
|
|
596
|
-
pick.token,
|
|
597
|
-
buildRegionInfo(pick.region),
|
|
598
|
-
{
|
|
599
|
-
type,
|
|
600
|
-
responseFormat
|
|
601
|
-
}
|
|
602
|
-
);
|
|
603
|
-
const taskInfo = collectTaskInfo(normalized, deps);
|
|
604
|
-
if (!taskInfo) {
|
|
605
|
-
if (isJson) {
|
|
606
|
-
deps.printCommandJson("task.get", deps.unwrapBody(normalized));
|
|
607
|
-
} else {
|
|
608
|
-
deps.printJson(deps.unwrapBody(normalized));
|
|
609
|
-
}
|
|
610
|
-
return;
|
|
611
|
-
}
|
|
612
|
-
if (isJson) deps.printCommandJson("task.get", taskInfo);
|
|
613
|
-
else printTaskInfo(taskInfo, deps);
|
|
657
|
+
const pick = await deps.pickDirectTokenForTask(deps.getSingleString(args, "token"), deps.getSingleString(args, "region"));
|
|
658
|
+
const normalized = await getTaskResponse(taskId, pick.token, buildRegionInfo(pick.region), { type, responseFormat });
|
|
659
|
+
outputTaskResult("task.get", normalized, Boolean(args.json), deps);
|
|
614
660
|
};
|
|
615
661
|
const handleTaskWait = async (argv) => {
|
|
616
662
|
const args = minimist2(argv, {
|
|
617
|
-
string: [
|
|
618
|
-
"token",
|
|
619
|
-
"region",
|
|
620
|
-
"task-id",
|
|
621
|
-
"type",
|
|
622
|
-
"response-format",
|
|
623
|
-
"wait-timeout-seconds",
|
|
624
|
-
"poll-interval-ms"
|
|
625
|
-
],
|
|
663
|
+
string: ["token", "region", "task-id", "type", "response-format", "wait-timeout-seconds", "poll-interval-ms"],
|
|
626
664
|
boolean: ["help", "json"]
|
|
627
665
|
});
|
|
628
666
|
if (args.help) {
|
|
@@ -633,41 +671,18 @@ ${deps.usageTaskGet()}`);
|
|
|
633
671
|
if (!taskId) deps.fail(`Missing required --task-id.
|
|
634
672
|
|
|
635
673
|
${deps.usageTaskWait()}`);
|
|
636
|
-
const token = deps.getSingleString(args, "token");
|
|
637
|
-
const region = deps.getRegionWithDefault(args);
|
|
638
|
-
const isJson = Boolean(args.json);
|
|
639
|
-
const body = {};
|
|
640
674
|
const type = parseTaskTypeOrFail(deps.getSingleString(args, "type"), deps);
|
|
641
675
|
const responseFormat = parseResponseFormatOrFail(deps.getSingleString(args, "response-format"), deps);
|
|
642
|
-
if (type) body.type = type;
|
|
643
|
-
body.response_format = responseFormat;
|
|
644
676
|
const waitTimeoutSeconds = parsePositiveNumberOption(args, "wait-timeout-seconds", deps);
|
|
645
|
-
if (waitTimeoutSeconds !== void 0) body.wait_timeout_seconds = waitTimeoutSeconds;
|
|
646
677
|
const pollIntervalMs = parsePositiveNumberOption(args, "poll-interval-ms", deps);
|
|
647
|
-
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
responseFormat,
|
|
656
|
-
waitTimeoutSeconds: typeof body.wait_timeout_seconds === "number" ? body.wait_timeout_seconds : void 0,
|
|
657
|
-
pollIntervalMs: typeof body.poll_interval_ms === "number" ? body.poll_interval_ms : void 0
|
|
658
|
-
}
|
|
659
|
-
);
|
|
660
|
-
const taskInfo = collectTaskInfo(normalized, deps);
|
|
661
|
-
if (!taskInfo) {
|
|
662
|
-
if (isJson) {
|
|
663
|
-
deps.printCommandJson("task.wait", deps.unwrapBody(normalized));
|
|
664
|
-
} else {
|
|
665
|
-
deps.printJson(deps.unwrapBody(normalized));
|
|
666
|
-
}
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
if (isJson) deps.printCommandJson("task.wait", taskInfo);
|
|
670
|
-
else printTaskInfo(taskInfo, deps);
|
|
678
|
+
const pick = await deps.pickDirectTokenForTask(deps.getSingleString(args, "token"), deps.getSingleString(args, "region"));
|
|
679
|
+
const normalized = await waitForTaskResponse(taskId, pick.token, buildRegionInfo(pick.region), {
|
|
680
|
+
type,
|
|
681
|
+
responseFormat,
|
|
682
|
+
waitTimeoutSeconds,
|
|
683
|
+
pollIntervalMs
|
|
684
|
+
});
|
|
685
|
+
outputTaskResult("task.wait", normalized, Boolean(args.json), deps);
|
|
671
686
|
};
|
|
672
687
|
const handleTaskList = async (argv) => {
|
|
673
688
|
const args = minimist2(argv, {
|
|
@@ -678,24 +693,18 @@ ${deps.usageTaskWait()}`);
|
|
|
678
693
|
console.log(deps.usageTaskList());
|
|
679
694
|
return;
|
|
680
695
|
}
|
|
681
|
-
const token = deps.getSingleString(args, "token");
|
|
682
|
-
const region = deps.getRegionWithDefault(args);
|
|
683
696
|
const type = deps.getSingleString(args, "type");
|
|
684
|
-
const countRaw = deps.getSingleString(args, "count");
|
|
685
|
-
const count = countRaw ? Number(countRaw) : 20;
|
|
686
|
-
const isJson = Boolean(args.json);
|
|
687
697
|
if (type && type !== "image" && type !== "video" && type !== "all") {
|
|
688
698
|
deps.fail(`Invalid --type: ${type}. Use image, video, or all.`);
|
|
689
699
|
}
|
|
690
|
-
const
|
|
691
|
-
const
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
);
|
|
700
|
+
const countRaw = deps.getSingleString(args, "count");
|
|
701
|
+
const count = countRaw ? Number(countRaw) : 20;
|
|
702
|
+
const isJson = Boolean(args.json);
|
|
703
|
+
const pick = await deps.pickDirectTokenForTask(deps.getSingleString(args, "token"), deps.getSingleString(args, "region"));
|
|
704
|
+
const result = await getAssetList(pick.token, buildRegionInfo(pick.region), {
|
|
705
|
+
count: Number.isFinite(count) && count > 0 ? count : 20,
|
|
706
|
+
type
|
|
707
|
+
});
|
|
699
708
|
if (isJson) {
|
|
700
709
|
deps.printCommandJson("task.list", {
|
|
701
710
|
has_more: result.hasMore,
|
|
@@ -714,9 +723,7 @@ ${deps.usageTaskWait()}`);
|
|
|
714
723
|
const modelShort = item.modelName || item.modelReqKey || "-";
|
|
715
724
|
const promptShort = item.prompt.length > 50 ? item.prompt.slice(0, 50) + "..." : item.prompt;
|
|
716
725
|
console.log(`${item.id} ${typeLabel} ${statusLabel.padEnd(4)} ${time} ${modelShort.padEnd(20)} ${promptShort}`);
|
|
717
|
-
if (item.imageUrl) {
|
|
718
|
-
console.log(` ${item.imageUrl}`);
|
|
719
|
-
}
|
|
726
|
+
if (item.imageUrl) console.log(` ${item.imageUrl}`);
|
|
720
727
|
}
|
|
721
728
|
};
|
|
722
729
|
return {
|
|
@@ -726,12 +733,12 @@ ${deps.usageTaskWait()}`);
|
|
|
726
733
|
handleTaskWait,
|
|
727
734
|
handleTaskList,
|
|
728
735
|
printTaskInfo: (task) => {
|
|
729
|
-
const
|
|
730
|
-
if (!
|
|
736
|
+
const info = collectTaskInfo(task, deps);
|
|
737
|
+
if (!info) {
|
|
731
738
|
deps.printJson(task);
|
|
732
739
|
return;
|
|
733
740
|
}
|
|
734
|
-
printTaskInfo(
|
|
741
|
+
printTaskInfo(info, deps);
|
|
735
742
|
}
|
|
736
743
|
};
|
|
737
744
|
}
|
|
@@ -965,7 +972,19 @@ function applyWaitOptionsToBody(body, args, deps, includeWaitFlag = true) {
|
|
|
965
972
|
return wait;
|
|
966
973
|
}
|
|
967
974
|
async function downloadBinary(url, deps) {
|
|
968
|
-
const
|
|
975
|
+
const controller = new AbortController();
|
|
976
|
+
const timeout = setTimeout(() => controller.abort(), 12e4);
|
|
977
|
+
let response;
|
|
978
|
+
try {
|
|
979
|
+
response = await fetch(url, { signal: controller.signal });
|
|
980
|
+
} catch (err) {
|
|
981
|
+
clearTimeout(timeout);
|
|
982
|
+
if (err.name === "AbortError") {
|
|
983
|
+
deps.fail(`Download timed out after 120s: ${url}`);
|
|
984
|
+
}
|
|
985
|
+
throw err;
|
|
986
|
+
}
|
|
987
|
+
clearTimeout(timeout);
|
|
969
988
|
if (!response.ok) {
|
|
970
989
|
deps.fail(`Download failed (${response.status}): ${url}`);
|
|
971
990
|
}
|
|
@@ -1034,6 +1053,9 @@ function createMediaCommandHandlers(deps) {
|
|
|
1034
1053
|
if (!Number.isFinite(parsed)) {
|
|
1035
1054
|
deps.fail(`Invalid --sample-strength: ${sampleStrengthRaw}`);
|
|
1036
1055
|
}
|
|
1056
|
+
if (parsed < 0 || parsed > 1) {
|
|
1057
|
+
deps.fail(`Invalid --sample-strength: ${sampleStrengthRaw} (must be between 0 and 1)`);
|
|
1058
|
+
}
|
|
1037
1059
|
body.sample_strength = parsed;
|
|
1038
1060
|
}
|
|
1039
1061
|
const pick = await deps.pickDirectTokenForGeneration(
|
|
@@ -1351,7 +1373,13 @@ import { existsSync } from "fs";
|
|
|
1351
1373
|
import path4 from "path";
|
|
1352
1374
|
import os from "os";
|
|
1353
1375
|
import minimist4 from "minimist";
|
|
1354
|
-
var LOGIN_SCRIPT = path4.join(
|
|
1376
|
+
var LOGIN_SCRIPT = path4.join(
|
|
1377
|
+
path4.dirname(new URL(import.meta.url).pathname),
|
|
1378
|
+
"..",
|
|
1379
|
+
"..",
|
|
1380
|
+
"scripts",
|
|
1381
|
+
"jimeng_login_helper.py"
|
|
1382
|
+
);
|
|
1355
1383
|
function createLoginCommandHandler(deps) {
|
|
1356
1384
|
return async (argv) => {
|
|
1357
1385
|
const args = minimist4(argv, {
|
|
@@ -1555,10 +1583,20 @@ function usageRoot() {
|
|
|
1555
1583
|
}
|
|
1556
1584
|
function usageModelsList() {
|
|
1557
1585
|
return buildUsageText(" jimeng models list [options]", [
|
|
1558
|
-
" --
|
|
1586
|
+
" --token <token> Query with specific token",
|
|
1587
|
+
" --region <region> Query with specific region (cn/us/hk/jp/sg)",
|
|
1588
|
+
" --all Query all tokens in pool, grouped by token/region",
|
|
1559
1589
|
" --verbose Print rich model fields",
|
|
1560
1590
|
" --json Print full JSON response",
|
|
1561
1591
|
HELP_OPTION
|
|
1592
|
+
], [
|
|
1593
|
+
{
|
|
1594
|
+
title: "Notes:",
|
|
1595
|
+
lines: [
|
|
1596
|
+
" Without --token, --region, or --all, uses the first available token in pool.",
|
|
1597
|
+
" With --all, queries every enabled+live token and groups results by token/region."
|
|
1598
|
+
]
|
|
1599
|
+
}
|
|
1562
1600
|
]);
|
|
1563
1601
|
}
|
|
1564
1602
|
function usageModelsRefresh() {
|
|
@@ -1718,7 +1756,7 @@ function usageVideoGenerate() {
|
|
|
1718
1756
|
function usageTaskGet() {
|
|
1719
1757
|
return buildUsageText(" jimeng task get --task-id <id> [options]", [
|
|
1720
1758
|
" --token <token> Optional, override token-pool selection",
|
|
1721
|
-
" --region <region>
|
|
1759
|
+
" --region <region> Filter token by region (cn/us/hk/jp/sg)",
|
|
1722
1760
|
" --task-id <id> Required history/task id",
|
|
1723
1761
|
" --type <type> Optional image or video",
|
|
1724
1762
|
" --response-format <fmt> Optional url or b64_json",
|
|
@@ -1729,7 +1767,7 @@ function usageTaskGet() {
|
|
|
1729
1767
|
function usageTaskWait() {
|
|
1730
1768
|
return buildUsageText(" jimeng task wait --task-id <id> [options]", [
|
|
1731
1769
|
" --token <token> Optional, override token-pool selection",
|
|
1732
|
-
" --region <region>
|
|
1770
|
+
" --region <region> Filter token by region (cn/us/hk/jp/sg)",
|
|
1733
1771
|
" --task-id <id> Required history/task id",
|
|
1734
1772
|
" --type <type> Optional image or video",
|
|
1735
1773
|
" --response-format <fmt> Optional url or b64_json",
|
|
@@ -1742,7 +1780,7 @@ function usageTaskWait() {
|
|
|
1742
1780
|
function usageTaskList() {
|
|
1743
1781
|
return buildUsageText(" jimeng task list [options]", [
|
|
1744
1782
|
" --token <token> Optional, override token-pool selection",
|
|
1745
|
-
" --region <region>
|
|
1783
|
+
" --region <region> Filter token by region (cn/us/hk/jp/sg)",
|
|
1746
1784
|
" --type <type> Filter by type: image, video, or all (default all)",
|
|
1747
1785
|
" --count <num> Number of items per page (default 20)",
|
|
1748
1786
|
JSON_OPTION,
|
|
@@ -1887,7 +1925,6 @@ var queryHandlers = createQueryCommandHandlers({
|
|
|
1887
1925
|
usageTaskWait,
|
|
1888
1926
|
usageTaskList,
|
|
1889
1927
|
getSingleString,
|
|
1890
|
-
getRegionWithDefault,
|
|
1891
1928
|
parseRegionOrFail,
|
|
1892
1929
|
ensureTokenPoolReady,
|
|
1893
1930
|
pickDirectTokenForTask,
|