bailian-cli-core 1.4.2 → 1.6.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/index.d.mts +988 -10
- package/dist/index.mjs +65 -3236
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,2466 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { dirname, join as join$1 } from "node:path";
|
|
9
|
-
import { fileURLToPath } from "node:url";
|
|
10
|
-
|
|
11
|
-
var
|
|
12
|
-
|
|
13
|
-
var
|
|
14
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
15
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
16
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
17
|
-
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
18
|
-
var __copyProps = (to, from, except, desc) => {
|
|
19
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
20
|
-
key = keys[i];
|
|
21
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
22
|
-
get: ((k) => from[k]).bind(null, key),
|
|
23
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
return to;
|
|
27
|
-
};
|
|
28
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
29
|
-
value: mod,
|
|
30
|
-
enumerable: true
|
|
31
|
-
}) : target, mod));
|
|
32
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
33
|
-
//#endregion
|
|
34
|
-
//#region src/errors/codes.ts
|
|
35
|
-
const ExitCode = {
|
|
36
|
-
SUCCESS: 0,
|
|
37
|
-
GENERAL: 1,
|
|
38
|
-
USAGE: 2,
|
|
39
|
-
AUTH: 3,
|
|
40
|
-
QUOTA: 4,
|
|
41
|
-
TIMEOUT: 5,
|
|
42
|
-
NETWORK: 6,
|
|
43
|
-
CONTENT_FILTER: 10
|
|
44
|
-
};
|
|
45
|
-
//#endregion
|
|
46
|
-
//#region src/errors/base.ts
|
|
47
|
-
var BailianError = class extends Error {
|
|
48
|
-
exitCode;
|
|
49
|
-
hint;
|
|
50
|
-
api;
|
|
51
|
-
constructor(message, exitCode = ExitCode.GENERAL, hint, options) {
|
|
52
|
-
super(message, options?.cause !== void 0 ? { cause: options.cause } : void 0);
|
|
53
|
-
this.name = "BailianError";
|
|
54
|
-
this.exitCode = exitCode;
|
|
55
|
-
this.hint = hint;
|
|
56
|
-
this.api = options?.api;
|
|
57
|
-
}
|
|
58
|
-
toJSON() {
|
|
59
|
-
const causeJson = serializeCause(this.cause);
|
|
60
|
-
return { error: {
|
|
61
|
-
code: this.exitCode,
|
|
62
|
-
message: this.message,
|
|
63
|
-
...this.hint ? { hint: this.hint } : {},
|
|
64
|
-
...this.api?.httpStatus !== void 0 ? { http_status: this.api.httpStatus } : {},
|
|
65
|
-
...this.api?.apiCode ? { api_code: this.api.apiCode } : {},
|
|
66
|
-
...this.api?.requestId ? { request_id: this.api.requestId } : {},
|
|
67
|
-
...causeJson ? { cause: causeJson } : {}
|
|
68
|
-
} };
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
function serializeCause(cause) {
|
|
72
|
-
if (cause == null) return void 0;
|
|
73
|
-
if (cause instanceof Error) {
|
|
74
|
-
const out = { message: cause.message };
|
|
75
|
-
const code = cause.code;
|
|
76
|
-
if (code) out.code = code;
|
|
77
|
-
return out;
|
|
78
|
-
}
|
|
79
|
-
if (typeof cause === "string" || typeof cause === "number" || typeof cause === "boolean") return { message: String(cause) };
|
|
80
|
-
try {
|
|
81
|
-
return { message: JSON.stringify(cause) };
|
|
82
|
-
} catch {
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
//#endregion
|
|
87
|
-
//#region src/errors/api.ts
|
|
88
|
-
function mapApiError(status, body, _url) {
|
|
89
|
-
const apiMsg = body.error?.message || body.message || `HTTP ${status}`;
|
|
90
|
-
const rawCode = body.error?.type ?? body.code;
|
|
91
|
-
const apiCode = typeof rawCode === "string" ? rawCode : typeof rawCode === "number" ? String(rawCode) : void 0;
|
|
92
|
-
return new BailianError(apiMsg, ExitCode.GENERAL, void 0, { api: {
|
|
93
|
-
httpStatus: status,
|
|
94
|
-
apiCode,
|
|
95
|
-
requestId: body.request_id
|
|
96
|
-
} });
|
|
97
|
-
}
|
|
98
|
-
//#endregion
|
|
99
|
-
//#region src/config/schema.ts
|
|
100
|
-
const REGIONS = {
|
|
101
|
-
cn: "https://dashscope.aliyuncs.com",
|
|
102
|
-
us: "https://dashscope-us.aliyuncs.com",
|
|
103
|
-
intl: "https://dashscope-intl.aliyuncs.com"
|
|
104
|
-
};
|
|
105
|
-
const DOCS_HOSTS = {
|
|
106
|
-
cn: "https://help.aliyun.com/zh/model-studio",
|
|
107
|
-
us: "https://help.aliyun.com/zh/model-studio",
|
|
108
|
-
intl: "https://help.aliyun.com/zh/model-studio"
|
|
109
|
-
};
|
|
110
|
-
const BAILIAN_HOST = "https://bailian.cn-beijing.aliyuncs.com";
|
|
111
|
-
const VALID_OUTPUTS = new Set(["text", "json"]);
|
|
112
|
-
const VALID_CONSOLE_SITES = new Set(["domestic", "international"]);
|
|
113
|
-
/**
|
|
114
|
-
* A syntactically valid absolute http(s) URL. Used to validate `base_url`
|
|
115
|
-
* from the config file: the credential-bearing client
|
|
116
|
-
* sends the Bearer token to these origins, so a bare `startsWith("http")` check
|
|
117
|
-
* (which also accepts e.g. "httpfoo://…") is too loose.
|
|
118
|
-
*/
|
|
119
|
-
function isHttpUrl(value) {
|
|
120
|
-
try {
|
|
121
|
-
const u = new URL(value);
|
|
122
|
-
return u.protocol === "http:" || u.protocol === "https:";
|
|
123
|
-
} catch {
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
function parseConfigFile(raw) {
|
|
128
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
129
|
-
const obj = raw;
|
|
130
|
-
const out = {};
|
|
131
|
-
if (typeof obj.api_key === "string") out.api_key = obj.api_key;
|
|
132
|
-
if (typeof obj.access_token === "string" && obj.access_token.length > 0) out.access_token = obj.access_token;
|
|
133
|
-
else if (typeof obj.accessToken === "string" && obj.accessToken.length > 0) out.access_token = obj.accessToken;
|
|
134
|
-
if (typeof obj.base_url === "string" && isHttpUrl(obj.base_url)) out.base_url = obj.base_url;
|
|
135
|
-
if (typeof obj.output === "string" && VALID_OUTPUTS.has(obj.output)) out.output = obj.output;
|
|
136
|
-
if (typeof obj.output_dir === "string" && obj.output_dir.length > 0) out.output_dir = obj.output_dir;
|
|
137
|
-
if (typeof obj.timeout === "number" && obj.timeout > 0) out.timeout = obj.timeout;
|
|
138
|
-
if (typeof obj.default_text_model === "string" && obj.default_text_model.length > 0) out.default_text_model = obj.default_text_model;
|
|
139
|
-
if (typeof obj.default_video_model === "string" && obj.default_video_model.length > 0) out.default_video_model = obj.default_video_model;
|
|
140
|
-
if (typeof obj.default_image_model === "string" && obj.default_image_model.length > 0) out.default_image_model = obj.default_image_model;
|
|
141
|
-
if (typeof obj.default_speech_model === "string" && obj.default_speech_model.length > 0) out.default_speech_model = obj.default_speech_model;
|
|
142
|
-
if (typeof obj.default_omni_model === "string" && obj.default_omni_model.length > 0) out.default_omni_model = obj.default_omni_model;
|
|
143
|
-
if (typeof obj.access_key_id === "string" && obj.access_key_id.length > 0) out.access_key_id = obj.access_key_id;
|
|
144
|
-
if (typeof obj.access_key_secret === "string" && obj.access_key_secret.length > 0) out.access_key_secret = obj.access_key_secret;
|
|
145
|
-
if (typeof obj.workspace_id === "string" && obj.workspace_id.length > 0) out.workspace_id = obj.workspace_id;
|
|
146
|
-
if (typeof obj.console_site === "string" && VALID_CONSOLE_SITES.has(obj.console_site)) out.console_site = obj.console_site;
|
|
147
|
-
if (typeof obj.console_region === "string" && obj.console_region.length > 0) out.console_region = obj.console_region;
|
|
148
|
-
if (typeof obj.console_switch_agent === "number" && obj.console_switch_agent > 0) out.console_switch_agent = obj.console_switch_agent;
|
|
149
|
-
if (typeof obj.telemetry === "boolean") out.telemetry = obj.telemetry;
|
|
150
|
-
return out;
|
|
151
|
-
}
|
|
152
|
-
//#endregion
|
|
153
|
-
//#region src/config/paths.ts
|
|
154
|
-
const CONFIG_DIR_NAME = ".bailian";
|
|
155
|
-
function getConfigDir() {
|
|
156
|
-
if (process.env.BAILIAN_CONFIG_DIR) return process.env.BAILIAN_CONFIG_DIR;
|
|
157
|
-
return join(homedir(), CONFIG_DIR_NAME);
|
|
158
|
-
}
|
|
159
|
-
function getConfigPath() {
|
|
160
|
-
return join(getConfigDir(), "config.json");
|
|
161
|
-
}
|
|
162
|
-
function getCredentialsPath() {
|
|
163
|
-
return join(getConfigDir(), "credentials.json");
|
|
164
|
-
}
|
|
165
|
-
async function ensureConfigDir() {
|
|
166
|
-
const dir = getConfigDir();
|
|
167
|
-
const fs = await import("fs/promises");
|
|
168
|
-
await fs.mkdir(dir, {
|
|
169
|
-
recursive: true,
|
|
170
|
-
mode: 448
|
|
171
|
-
});
|
|
172
|
-
try {
|
|
173
|
-
await fs.chmod(dir, 448);
|
|
174
|
-
} catch {}
|
|
175
|
-
}
|
|
176
|
-
//#endregion
|
|
177
|
-
//#region src/output/text.ts
|
|
178
|
-
function formatText(data) {
|
|
179
|
-
return stringify(data).replace(/\n$/, "");
|
|
180
|
-
}
|
|
181
|
-
//#endregion
|
|
182
|
-
//#region src/output/json.ts
|
|
183
|
-
function formatJson(data) {
|
|
184
|
-
return JSON.stringify(data, null, 2);
|
|
185
|
-
}
|
|
186
|
-
function formatErrorJson(code, message, hint) {
|
|
187
|
-
return JSON.stringify({ error: {
|
|
188
|
-
code,
|
|
189
|
-
message,
|
|
190
|
-
...hint ? { hint } : {}
|
|
191
|
-
} }, null, 2);
|
|
192
|
-
}
|
|
193
|
-
//#endregion
|
|
194
|
-
//#region src/output/formatter.ts
|
|
195
|
-
function detectOutputFormat(flagValue) {
|
|
196
|
-
if (flagValue === "json" || flagValue === "text") return flagValue;
|
|
197
|
-
if (!process.stdout.isTTY) return "json";
|
|
198
|
-
return "text";
|
|
199
|
-
}
|
|
200
|
-
function formatOutput(data, format) {
|
|
201
|
-
switch (format) {
|
|
202
|
-
case "json": return formatJson(data);
|
|
203
|
-
case "text": return formatText(data);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
//#endregion
|
|
207
|
-
//#region src/config/loader.ts
|
|
208
|
-
function readConfigFile() {
|
|
209
|
-
const path = getConfigPath();
|
|
210
|
-
if (!existsSync(path)) return {};
|
|
211
|
-
try {
|
|
212
|
-
return parseConfigFile(JSON.parse(readFileSync(path, "utf-8")));
|
|
213
|
-
} catch (err) {
|
|
214
|
-
const e = err;
|
|
215
|
-
if (e instanceof SyntaxError || e.message.includes("JSON")) console.warn("Warning: config file is corrupted; using defaults.");
|
|
216
|
-
return {};
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
async function writeConfigFile(data) {
|
|
220
|
-
await ensureConfigDir();
|
|
221
|
-
const path = getConfigPath();
|
|
222
|
-
const tmp = path + ".tmp";
|
|
223
|
-
writeFileSync(tmp, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
|
|
224
|
-
renameSync(tmp, path);
|
|
225
|
-
}
|
|
226
|
-
function loadConfig(flags) {
|
|
227
|
-
const file = readConfigFile();
|
|
228
|
-
const apiKey = flags.apiKey || void 0;
|
|
229
|
-
const fileApiKey = file.api_key;
|
|
230
|
-
const accessTokenEnv = process.env.DASHSCOPE_ACCESS_TOKEN?.trim() || void 0;
|
|
231
|
-
const fileAccessToken = file.access_token?.trim() || void 0;
|
|
232
|
-
const baseUrl = flags.baseUrl || file.base_url || process.env.DASHSCOPE_BASE_URL || REGIONS.cn;
|
|
233
|
-
const output = detectOutputFormat(flags.output || process.env.DASHSCOPE_OUTPUT || file.output);
|
|
234
|
-
const envTimeout = process.env.DASHSCOPE_TIMEOUT ? Number(process.env.DASHSCOPE_TIMEOUT) : void 0;
|
|
235
|
-
const validEnvTimeout = envTimeout !== void 0 && Number.isFinite(envTimeout) && envTimeout > 0 ? envTimeout : void 0;
|
|
236
|
-
const timeout = flags.timeout ?? validEnvTimeout ?? file.timeout ?? 300;
|
|
237
|
-
if (!Number.isFinite(timeout) || timeout <= 0) throw new BailianError("Timeout must be a positive finite number.", ExitCode.USAGE);
|
|
238
|
-
return {
|
|
239
|
-
apiKey,
|
|
240
|
-
accessTokenEnv,
|
|
241
|
-
fileAccessToken,
|
|
242
|
-
fileApiKey,
|
|
243
|
-
configPath: getConfigPath(),
|
|
244
|
-
baseUrl,
|
|
245
|
-
output,
|
|
246
|
-
outputDir: file.output_dir || void 0,
|
|
247
|
-
timeout,
|
|
248
|
-
defaultTextModel: file.default_text_model,
|
|
249
|
-
defaultVideoModel: file.default_video_model,
|
|
250
|
-
defaultImageModel: file.default_image_model,
|
|
251
|
-
defaultSpeechModel: file.default_speech_model,
|
|
252
|
-
defaultOmniModel: file.default_omni_model,
|
|
253
|
-
accessKeyId: process.env.ALIBABA_CLOUD_ACCESS_KEY_ID || file.access_key_id || void 0,
|
|
254
|
-
accessKeySecret: process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET || file.access_key_secret || void 0,
|
|
255
|
-
workspaceId: process.env.BAILIAN_WORKSPACE_ID || file.workspace_id || void 0,
|
|
256
|
-
consoleSite: flags.consoleSite || file.console_site || void 0,
|
|
257
|
-
consoleRegion: flags.consoleRegion || file.console_region || void 0,
|
|
258
|
-
consoleSwitchAgent: flags.consoleSwitchAgent || file.console_switch_agent || void 0,
|
|
259
|
-
verbose: flags.verbose || process.env.DASHSCOPE_VERBOSE === "1",
|
|
260
|
-
quiet: flags.quiet || false,
|
|
261
|
-
noColor: flags.noColor || process.env.NO_COLOR !== void 0 || !process.stdout.isTTY,
|
|
262
|
-
yes: flags.yes || false,
|
|
263
|
-
dryRun: flags.dryRun || false,
|
|
264
|
-
nonInteractive: flags.nonInteractive || false,
|
|
265
|
-
async: flags.async || false,
|
|
266
|
-
telemetry: process.env.DO_NOT_TRACK === "1" ? false : file.telemetry ?? true
|
|
267
|
-
};
|
|
268
|
-
}
|
|
269
|
-
//#endregion
|
|
270
|
-
//#region src/auth/credentials.ts
|
|
271
|
-
function loadApiKeyFromConfig() {
|
|
272
|
-
const path = getConfigPath();
|
|
273
|
-
if (!existsSync(path)) return null;
|
|
274
|
-
try {
|
|
275
|
-
const raw = readFileSync(path, "utf-8");
|
|
276
|
-
const data = JSON.parse(raw);
|
|
277
|
-
if (typeof data.api_key === "string" && data.api_key.length > 0) return data.api_key;
|
|
278
|
-
return null;
|
|
279
|
-
} catch {
|
|
280
|
-
return null;
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
async function saveApiKeyToConfig(apiKey) {
|
|
284
|
-
await ensureConfigDir();
|
|
285
|
-
const path = getConfigPath();
|
|
286
|
-
let existing = {};
|
|
287
|
-
try {
|
|
288
|
-
existing = JSON.parse(readFileSync(path, "utf-8"));
|
|
289
|
-
} catch {}
|
|
290
|
-
existing.api_key = apiKey;
|
|
291
|
-
const tmp = path + ".tmp";
|
|
292
|
-
writeFileSync(tmp, JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
|
|
293
|
-
renameSync(tmp, path);
|
|
294
|
-
}
|
|
295
|
-
async function clearApiKey() {
|
|
296
|
-
const path = getConfigPath();
|
|
297
|
-
if (!existsSync(path)) return;
|
|
298
|
-
try {
|
|
299
|
-
const existing = JSON.parse(readFileSync(path, "utf-8"));
|
|
300
|
-
delete existing.api_key;
|
|
301
|
-
delete existing.access_token;
|
|
302
|
-
const tmp = path + ".tmp";
|
|
303
|
-
writeFileSync(tmp, JSON.stringify(existing, null, 2) + "\n", { mode: 384 });
|
|
304
|
-
renameSync(tmp, path);
|
|
305
|
-
} catch {}
|
|
306
|
-
}
|
|
307
|
-
//#endregion
|
|
308
|
-
//#region src/auth/resolver.ts
|
|
309
|
-
async function resolveCredential(config) {
|
|
310
|
-
if (config.apiKey) return {
|
|
311
|
-
token: config.apiKey,
|
|
312
|
-
method: "api-key",
|
|
313
|
-
source: "flag"
|
|
314
|
-
};
|
|
315
|
-
if (config.fileApiKey) return {
|
|
316
|
-
token: config.fileApiKey,
|
|
317
|
-
method: "api-key",
|
|
318
|
-
source: "config.json"
|
|
319
|
-
};
|
|
320
|
-
if (config.accessTokenEnv) return {
|
|
321
|
-
token: config.accessTokenEnv,
|
|
322
|
-
method: "access-token",
|
|
323
|
-
source: "DASHSCOPE_ACCESS_TOKEN"
|
|
324
|
-
};
|
|
325
|
-
if (config.fileAccessToken) return {
|
|
326
|
-
token: config.fileAccessToken,
|
|
327
|
-
method: "access-token",
|
|
328
|
-
source: "config.json"
|
|
329
|
-
};
|
|
330
|
-
if (process.env.DASHSCOPE_API_KEY) return {
|
|
331
|
-
token: process.env.DASHSCOPE_API_KEY,
|
|
332
|
-
method: "api-key",
|
|
333
|
-
source: "DASHSCOPE_API_KEY"
|
|
334
|
-
};
|
|
335
|
-
throw new BailianError("No credentials found.", ExitCode.AUTH, "Set DASHSCOPE_API_KEY environment variable, pass --api-key, or configure a key.");
|
|
336
|
-
}
|
|
337
|
-
/**
|
|
338
|
-
* Credential for Bailian **console** CLI gateway only (`callConsoleGateway`).
|
|
339
|
-
* DashScope API keys are not valid Bearer tokens for this gateway — use env/file
|
|
340
|
-
* `access_token` even when `api_key` is also present in config.
|
|
341
|
-
*/
|
|
342
|
-
/** Thrown when `callConsoleGateway` has no usable console session token. */
|
|
343
|
-
const CONSOLE_GATEWAY_NO_TOKEN_MESSAGE = "No console access token found.";
|
|
344
|
-
async function resolveConsoleGatewayCredential(config) {
|
|
345
|
-
if (config.accessTokenEnv) return {
|
|
346
|
-
token: config.accessTokenEnv,
|
|
347
|
-
method: "access-token",
|
|
348
|
-
source: "DASHSCOPE_ACCESS_TOKEN"
|
|
349
|
-
};
|
|
350
|
-
if (config.fileAccessToken) return {
|
|
351
|
-
token: config.fileAccessToken,
|
|
352
|
-
method: "access-token",
|
|
353
|
-
source: "config.json"
|
|
354
|
-
};
|
|
355
|
-
throw new BailianError(CONSOLE_GATEWAY_NO_TOKEN_MESSAGE, ExitCode.AUTH, "Run `bl auth login --console` or set DASHSCOPE_ACCESS_TOKEN.");
|
|
356
|
-
}
|
|
357
|
-
//#endregion
|
|
358
|
-
//#region src/client/ak-sign.ts
|
|
359
|
-
/**
|
|
360
|
-
* Alibaba Cloud V3 Signature (ROA style) for Bailian Cloud API.
|
|
361
|
-
*
|
|
362
|
-
* Used by Knowledge Base Retrieve API which requires AK/SK authentication
|
|
363
|
-
* instead of Bearer token.
|
|
364
|
-
*
|
|
365
|
-
* Reference: https://help.aliyun.com/document_detail/2712195.html
|
|
366
|
-
*/
|
|
367
|
-
function signRequest(cfg) {
|
|
368
|
-
const method = cfg.method ?? "POST";
|
|
369
|
-
const dateISO = (/* @__PURE__ */ new Date()).toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
370
|
-
const nonce = randomUUID();
|
|
371
|
-
const hashedBody = sha256Hex(cfg.body);
|
|
372
|
-
const headers = {
|
|
373
|
-
host: cfg.host,
|
|
374
|
-
"x-acs-action": cfg.action,
|
|
375
|
-
"x-acs-version": cfg.version,
|
|
376
|
-
"x-acs-date": dateISO,
|
|
377
|
-
"x-acs-signature-nonce": nonce,
|
|
378
|
-
"x-acs-content-sha256": hashedBody,
|
|
379
|
-
"content-type": "application/json"
|
|
380
|
-
};
|
|
381
|
-
const signedHeaderKeys = Object.keys(headers).filter((k) => k === "host" || k === "content-type" || k.startsWith("x-acs-")).sort();
|
|
382
|
-
const canonicalHeaders = signedHeaderKeys.map((k) => `${k}:${headers[k]}`).join("\n") + "\n";
|
|
383
|
-
const signedHeadersStr = signedHeaderKeys.join(";");
|
|
384
|
-
const canonicalRequest = [
|
|
385
|
-
method,
|
|
386
|
-
cfg.pathname,
|
|
387
|
-
"",
|
|
388
|
-
canonicalHeaders,
|
|
389
|
-
signedHeadersStr,
|
|
390
|
-
hashedBody
|
|
391
|
-
].join("\n");
|
|
392
|
-
const algorithm = "ACS3-HMAC-SHA256";
|
|
393
|
-
const stringToSign = `${algorithm}\n${sha256Hex(canonicalRequest)}`;
|
|
394
|
-
const signature = hmacSHA256Hex(cfg.accessKeySecret, stringToSign);
|
|
395
|
-
headers["authorization"] = `${algorithm} Credential=${cfg.accessKeyId},SignedHeaders=${signedHeadersStr},Signature=${signature}`;
|
|
396
|
-
return headers;
|
|
397
|
-
}
|
|
398
|
-
function sha256Hex(data) {
|
|
399
|
-
return createHash("sha256").update(data, "utf8").digest("hex");
|
|
400
|
-
}
|
|
401
|
-
function hmacSHA256Hex(key, data) {
|
|
402
|
-
return createHmac("sha256", key).update(data, "utf8").digest("hex");
|
|
403
|
-
}
|
|
404
|
-
//#endregion
|
|
405
|
-
//#region src/client/endpoints.ts
|
|
406
|
-
function chatEndpoint(baseUrl) {
|
|
407
|
-
return `${baseUrl}/compatible-mode/v1/chat/completions`;
|
|
408
|
-
}
|
|
409
|
-
function imageEndpoint(baseUrl) {
|
|
410
|
-
return `${baseUrl}/api/v1/services/aigc/image-generation/generation`;
|
|
411
|
-
}
|
|
412
|
-
function imageSyncEndpoint(baseUrl) {
|
|
413
|
-
return `${baseUrl}/api/v1/services/aigc/multimodal-generation/generation`;
|
|
414
|
-
}
|
|
415
|
-
function videoGenerateEndpoint(baseUrl) {
|
|
416
|
-
return `${baseUrl}/api/v1/services/aigc/video-generation/video-synthesis`;
|
|
417
|
-
}
|
|
418
|
-
function taskEndpoint(baseUrl, taskId) {
|
|
419
|
-
return `${baseUrl}/api/v1/tasks/${encodeURIComponent(taskId)}`;
|
|
420
|
-
}
|
|
421
|
-
function appCompletionEndpoint(baseUrl, appId) {
|
|
422
|
-
return `${baseUrl}/api/v1/apps/${encodeURIComponent(appId)}/completion`;
|
|
423
|
-
}
|
|
424
|
-
function memoryAddEndpoint(baseUrl) {
|
|
425
|
-
return `${baseUrl}/api/v2/apps/memory/add`;
|
|
426
|
-
}
|
|
427
|
-
function memorySearchEndpoint(baseUrl) {
|
|
428
|
-
return `${baseUrl}/api/v2/apps/memory/memory_nodes/search`;
|
|
429
|
-
}
|
|
430
|
-
function memoryListEndpoint(baseUrl) {
|
|
431
|
-
return `${baseUrl}/api/v2/apps/memory/memory_nodes`;
|
|
432
|
-
}
|
|
433
|
-
function memoryNodeEndpoint(baseUrl, nodeId) {
|
|
434
|
-
return `${baseUrl}/api/v2/apps/memory/memory_nodes/${encodeURIComponent(nodeId)}`;
|
|
435
|
-
}
|
|
436
|
-
function speechSynthesizeEndpoint(baseUrl) {
|
|
437
|
-
return `${baseUrl}/api/v1/services/audio/tts/SpeechSynthesizer`;
|
|
438
|
-
}
|
|
439
|
-
function speechRecognizeEndpoint(baseUrl) {
|
|
440
|
-
return `${baseUrl}/api/v1/services/audio/asr/transcription`;
|
|
441
|
-
}
|
|
442
|
-
function profileSchemaEndpoint(baseUrl) {
|
|
443
|
-
return `${baseUrl}/api/v2/apps/memory/profile_schemas`;
|
|
444
|
-
}
|
|
445
|
-
function userProfileEndpoint(baseUrl, schemaId) {
|
|
446
|
-
return `${baseUrl}/api/v2/apps/memory/profile_schemas/${encodeURIComponent(schemaId)}/profiles`;
|
|
447
|
-
}
|
|
448
|
-
function knowledgeRetrieveEndpoint(baseUrl) {
|
|
449
|
-
return `${baseUrl}/api/v1/indices/rag/index/retrieve`;
|
|
450
|
-
}
|
|
451
|
-
function mcpWebSearchEndpoint(baseUrl) {
|
|
452
|
-
return `${baseUrl}/api/v1/mcps/WebSearch/mcp`;
|
|
453
|
-
}
|
|
454
|
-
//#endregion
|
|
455
|
-
//#region src/client/headers.ts
|
|
456
|
-
/**
|
|
457
|
-
* Shared HTTP request headers for all outgoing requests.
|
|
458
|
-
*
|
|
459
|
-
* Centralises the `x-dashscope-source-config` header so every fetch call
|
|
460
|
-
* (both via the central http client and the bypass paths) uses the
|
|
461
|
-
* same values from a single source of truth.
|
|
462
|
-
*/
|
|
463
|
-
const CHANNEL = "bailian-cli";
|
|
464
|
-
const TAGS = {
|
|
465
|
-
t1: "public",
|
|
466
|
-
t2: ""
|
|
467
|
-
};
|
|
468
|
-
const SOURCE_CONFIG = JSON.stringify({
|
|
469
|
-
channel: CHANNEL,
|
|
470
|
-
tags: TAGS
|
|
471
|
-
});
|
|
472
|
-
/** Standard tracking headers required on every outbound request. */
|
|
473
|
-
function trackingHeaders() {
|
|
474
|
-
return { "x-dashscope-source-config": SOURCE_CONFIG };
|
|
475
|
-
}
|
|
476
|
-
//#endregion
|
|
477
|
-
//#region src/utils/token.ts
|
|
478
|
-
function maskToken(token) {
|
|
479
|
-
return token.length > 8 ? `${token.slice(0, 4)}...${token.slice(-4)}` : "***";
|
|
480
|
-
}
|
|
481
|
-
//#endregion
|
|
482
|
-
//#region src/client/http.ts
|
|
483
|
-
/**
|
|
484
|
-
* Bailian requires `X-DashScope-OssResourceResolve: enable` on any request whose body
|
|
485
|
-
* references an `oss://` URL (returned by the upload API). Detected automatically here
|
|
486
|
-
* so callers don't need to track it manually.
|
|
487
|
-
*/
|
|
488
|
-
function bodyReferencesOssUrl(body) {
|
|
489
|
-
if (body == null || typeof body !== "object") return false;
|
|
490
|
-
if (body instanceof FormData) return false;
|
|
491
|
-
return JSON.stringify(body).includes("oss://");
|
|
492
|
-
}
|
|
493
|
-
async function request(config, opts) {
|
|
494
|
-
const isFormData = typeof FormData !== "undefined" && opts.body instanceof FormData;
|
|
495
|
-
const headers = {
|
|
496
|
-
"User-Agent": `${config.clientName ?? "bailian-cli-core"}/${config.clientVersion ?? "0.0.0-dev"}`,
|
|
497
|
-
...trackingHeaders(),
|
|
498
|
-
...opts.headers
|
|
499
|
-
};
|
|
500
|
-
if (!isFormData && !headers["Content-Type"]) headers["Content-Type"] = "application/json";
|
|
501
|
-
if (opts.async) headers["X-DashScope-Async"] = "enable";
|
|
502
|
-
if (bodyReferencesOssUrl(opts.body)) headers["X-DashScope-OssResourceResolve"] = "enable";
|
|
503
|
-
if (!opts.noAuth) {
|
|
504
|
-
const credential = await resolveCredential(config);
|
|
505
|
-
headers["Authorization"] = `Bearer ${credential.token}`;
|
|
506
|
-
if (config.verbose) {
|
|
507
|
-
console.error(`> ${opts.method ?? "GET"} ${opts.url}`);
|
|
508
|
-
console.error(`> Auth: ${maskToken(credential.token)}`);
|
|
509
|
-
console.error(`> x-dashscope-source-config: ${SOURCE_CONFIG}`);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
const requestSignal = createRequestSignal((opts.timeout ?? config.timeout) * 1e3, opts.signal);
|
|
513
|
-
const res = await fetch(opts.url, {
|
|
514
|
-
method: opts.method ?? "GET",
|
|
515
|
-
headers,
|
|
516
|
-
body: opts.body ? isFormData ? opts.body : JSON.stringify(opts.body) : void 0,
|
|
517
|
-
signal: requestSignal.signal
|
|
518
|
-
}).finally(requestSignal.cleanup);
|
|
519
|
-
if (config.verbose) {
|
|
520
|
-
console.error(`< ${res.status} ${res.statusText}`);
|
|
521
|
-
const reqId = res.headers.get("x-request-id");
|
|
522
|
-
if (reqId) console.error(`request_id: ${reqId}`);
|
|
523
|
-
}
|
|
524
|
-
if (!res.ok) {
|
|
525
|
-
let body = {};
|
|
526
|
-
try {
|
|
527
|
-
body = await res.json();
|
|
528
|
-
} catch {}
|
|
529
|
-
throw mapApiError(res.status, body, opts.url);
|
|
530
|
-
}
|
|
531
|
-
return res;
|
|
532
|
-
}
|
|
533
|
-
function createRequestSignal(timeoutMs, parentSignal) {
|
|
534
|
-
const controller = new AbortController();
|
|
535
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
536
|
-
const abortFromParent = () => controller.abort(parentSignal?.reason);
|
|
537
|
-
const cleanup = () => {
|
|
538
|
-
clearTimeout(timeout);
|
|
539
|
-
parentSignal?.removeEventListener("abort", abortFromParent);
|
|
540
|
-
};
|
|
541
|
-
if (parentSignal?.aborted) abortFromParent();
|
|
542
|
-
else parentSignal?.addEventListener("abort", abortFromParent, { once: true });
|
|
543
|
-
controller.signal.addEventListener("abort", cleanup, { once: true });
|
|
544
|
-
return {
|
|
545
|
-
signal: controller.signal,
|
|
546
|
-
cleanup
|
|
547
|
-
};
|
|
548
|
-
}
|
|
549
|
-
async function requestJson(config, opts) {
|
|
550
|
-
const res = await request(config, opts);
|
|
551
|
-
let data;
|
|
552
|
-
try {
|
|
553
|
-
data = await res.json();
|
|
554
|
-
} catch {
|
|
555
|
-
throw new BailianError(`API returned non-JSON response (${res.headers.get("content-type") || "unknown type"}). Server may be experiencing issues.`, ExitCode.GENERAL);
|
|
556
|
-
}
|
|
557
|
-
if (data.code && typeof data.code === "string" && data.code !== "200" && data.code !== "Success") throw mapApiError(200, { error: {
|
|
558
|
-
message: data.message,
|
|
559
|
-
type: data.code
|
|
560
|
-
} }, opts.url);
|
|
561
|
-
return data;
|
|
562
|
-
}
|
|
563
|
-
//#endregion
|
|
564
|
-
//#region src/client/mcp.ts
|
|
565
|
-
/**
|
|
566
|
-
* Compose the streamable-HTTP MCP endpoint for a Bailian MCP server.
|
|
567
|
-
* The path is `/api/v1/mcps/<serverCode>/mcp`; the `serverCode` is taken
|
|
568
|
-
* verbatim from `bl mcp list` (e.g. `WebSearch`, `market-cmapi00073529`).
|
|
569
|
-
*/
|
|
570
|
-
function bailianMcpUrl(baseUrl, serverCode) {
|
|
571
|
-
return `${baseUrl.replace(/\/$/, "")}/api/v1/mcps/${serverCode}/mcp`;
|
|
572
|
-
}
|
|
573
|
-
var McpClient = class {
|
|
574
|
-
url;
|
|
575
|
-
sessionId;
|
|
576
|
-
nextId = 1;
|
|
577
|
-
config;
|
|
578
|
-
authToken;
|
|
579
|
-
constructor(config, url) {
|
|
580
|
-
this.config = config;
|
|
581
|
-
this.url = url;
|
|
582
|
-
}
|
|
583
|
-
/** Initialize the MCP session. Must be called before any other method. */
|
|
584
|
-
async initialize() {
|
|
585
|
-
const credential = await resolveCredential(this.config);
|
|
586
|
-
this.authToken = credential.token;
|
|
587
|
-
const result = await this.rpc("initialize", {
|
|
588
|
-
protocolVersion: "2025-03-26",
|
|
589
|
-
capabilities: {},
|
|
590
|
-
clientInfo: {
|
|
591
|
-
name: this.config.clientName ?? "bailian-cli-core",
|
|
592
|
-
version: this.config.clientVersion ?? "0.0.0-dev"
|
|
593
|
-
}
|
|
594
|
-
});
|
|
595
|
-
if (this.config.verbose) {
|
|
596
|
-
console.error(`[MCP] Session initialized: ${this.sessionId ?? "no session"}`);
|
|
597
|
-
console.error(`[MCP] Server: ${JSON.stringify(result)}`);
|
|
598
|
-
}
|
|
599
|
-
await this.notify("notifications/initialized");
|
|
600
|
-
}
|
|
601
|
-
async listTools() {
|
|
602
|
-
return (await this.rpc("tools/list")).tools || [];
|
|
603
|
-
}
|
|
604
|
-
async callTool(name, args) {
|
|
605
|
-
return await this.rpc("tools/call", {
|
|
606
|
-
name,
|
|
607
|
-
arguments: args
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
async rpc(method, params) {
|
|
611
|
-
const body = {
|
|
612
|
-
jsonrpc: "2.0",
|
|
613
|
-
id: this.nextId++,
|
|
614
|
-
method,
|
|
615
|
-
...params ? { params } : {}
|
|
616
|
-
};
|
|
617
|
-
const data = await (await this.send(body)).json();
|
|
618
|
-
if (data.error) throw new BailianError(`MCP error (${data.error.code}): ${data.error.message}`, ExitCode.GENERAL);
|
|
619
|
-
return data.result;
|
|
620
|
-
}
|
|
621
|
-
async notify(method, params) {
|
|
622
|
-
const body = {
|
|
623
|
-
jsonrpc: "2.0",
|
|
624
|
-
method,
|
|
625
|
-
...params ? { params } : {}
|
|
626
|
-
};
|
|
627
|
-
await this.send(body);
|
|
628
|
-
}
|
|
629
|
-
async send(body) {
|
|
630
|
-
const headers = {
|
|
631
|
-
"Content-Type": "application/json",
|
|
632
|
-
Accept: "application/json, text/event-stream",
|
|
633
|
-
"User-Agent": `${this.config.clientName ?? "bailian-cli-core"}/${this.config.clientVersion ?? "0.0.0-dev"}`,
|
|
634
|
-
...trackingHeaders()
|
|
635
|
-
};
|
|
636
|
-
if (this.authToken) headers["Authorization"] = `Bearer ${this.authToken}`;
|
|
637
|
-
if (this.sessionId) headers["Mcp-Session-Id"] = this.sessionId;
|
|
638
|
-
if (this.config.verbose) {
|
|
639
|
-
console.error(`> POST ${this.url}`);
|
|
640
|
-
console.error(`> Method: ${body.method}`);
|
|
641
|
-
}
|
|
642
|
-
const timeoutMs = this.config.timeout * 1e3;
|
|
643
|
-
const res = await fetch(this.url, {
|
|
644
|
-
method: "POST",
|
|
645
|
-
headers,
|
|
646
|
-
body: JSON.stringify(body),
|
|
647
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
648
|
-
});
|
|
649
|
-
if (this.config.verbose) console.error(`< ${res.status} ${res.statusText}`);
|
|
650
|
-
const sid = res.headers.get("Mcp-Session-Id") || res.headers.get("mcp-session-id");
|
|
651
|
-
if (sid) this.sessionId = sid;
|
|
652
|
-
if (!res.ok) {
|
|
653
|
-
let errMsg = `MCP request failed: ${res.status} ${res.statusText}`;
|
|
654
|
-
try {
|
|
655
|
-
const errBody = await res.text();
|
|
656
|
-
if (errBody) errMsg += ` - ${errBody.slice(0, 500)}`;
|
|
657
|
-
} catch {}
|
|
658
|
-
throw new BailianError(errMsg, ExitCode.GENERAL);
|
|
659
|
-
}
|
|
660
|
-
return res;
|
|
661
|
-
}
|
|
662
|
-
};
|
|
663
|
-
//#endregion
|
|
664
|
-
//#region src/client/stream.ts
|
|
665
|
-
async function* parseSSE(response) {
|
|
666
|
-
const reader = response.body?.getReader();
|
|
667
|
-
if (!reader) return;
|
|
668
|
-
const decoder = new TextDecoder();
|
|
669
|
-
let buffer = "";
|
|
670
|
-
const MAX_SSE_BUFFER = 16 * 1024 * 1024;
|
|
671
|
-
try {
|
|
672
|
-
while (true) {
|
|
673
|
-
const { done, value } = await reader.read();
|
|
674
|
-
if (done) break;
|
|
675
|
-
buffer += decoder.decode(value, { stream: true });
|
|
676
|
-
if (buffer.length > MAX_SSE_BUFFER) throw new BailianError("SSE stream exceeded the maximum buffer size.", ExitCode.GENERAL);
|
|
677
|
-
const lines = buffer.split("\n");
|
|
678
|
-
buffer = lines.pop() || "";
|
|
679
|
-
let event = {};
|
|
680
|
-
for (const line of lines) {
|
|
681
|
-
if (line === "") {
|
|
682
|
-
if (event.data !== void 0) yield {
|
|
683
|
-
data: event.data,
|
|
684
|
-
event: event.event,
|
|
685
|
-
id: event.id
|
|
686
|
-
};
|
|
687
|
-
event = {};
|
|
688
|
-
continue;
|
|
689
|
-
}
|
|
690
|
-
if (line.startsWith(":")) continue;
|
|
691
|
-
const colonIndex = line.indexOf(":");
|
|
692
|
-
if (colonIndex === -1) continue;
|
|
693
|
-
const field = line.slice(0, colonIndex);
|
|
694
|
-
const value = line.slice(colonIndex + 1).trimStart();
|
|
695
|
-
switch (field) {
|
|
696
|
-
case "data":
|
|
697
|
-
event.data = event.data !== void 0 ? `${event.data}\n${value}` : value;
|
|
698
|
-
if (event.data.length > MAX_SSE_BUFFER) throw new BailianError("SSE event exceeded the maximum buffer size.", ExitCode.GENERAL);
|
|
699
|
-
break;
|
|
700
|
-
case "event":
|
|
701
|
-
event.event = value;
|
|
702
|
-
break;
|
|
703
|
-
case "id":
|
|
704
|
-
event.id = value;
|
|
705
|
-
break;
|
|
706
|
-
}
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
if (buffer.trim() && buffer.includes("data:")) {
|
|
710
|
-
const colonIndex = buffer.indexOf(":");
|
|
711
|
-
if (colonIndex !== -1) yield { data: buffer.slice(colonIndex + 1).trimStart() };
|
|
712
|
-
}
|
|
713
|
-
} finally {
|
|
714
|
-
reader.releaseLock();
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
//#endregion
|
|
718
|
-
//#region src/console/gateway.ts
|
|
719
|
-
const GATEWAY_PRODUCT = "sfm_bailian";
|
|
720
|
-
const REGION_GATEWAYS = {
|
|
721
|
-
"cn-beijing": {
|
|
722
|
-
domestic: {
|
|
723
|
-
csGateway: "bailian-cs.console.aliyun.com",
|
|
724
|
-
action: "BroadScopeAspnGateway"
|
|
725
|
-
},
|
|
726
|
-
international: {
|
|
727
|
-
csGateway: "bailian-cs.console.alibabacloud.com",
|
|
728
|
-
action: "BroadScopeAspnGateway"
|
|
729
|
-
}
|
|
730
|
-
},
|
|
731
|
-
"ap-southeast-1": {
|
|
732
|
-
domestic: {
|
|
733
|
-
csGateway: "modelstudio-cs.console.aliyun.com",
|
|
734
|
-
action: "IntlBroadScopeAspnGateway"
|
|
735
|
-
},
|
|
736
|
-
international: {
|
|
737
|
-
csGateway: "bailian-singapore-cs.alibabacloud.com",
|
|
738
|
-
action: "IntlBroadScopeAspnGateway"
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
};
|
|
742
|
-
function resolveGateway(region, site) {
|
|
743
|
-
return REGION_GATEWAYS[region]?.[site] ?? REGION_GATEWAYS["cn-beijing"][site];
|
|
744
|
-
}
|
|
745
|
-
/** Resolved console gateway settings (same defaults as {@link callConsoleGateway}). */
|
|
746
|
-
function effectiveConsoleGatewayConfig(config) {
|
|
747
|
-
const consoleRegion = config.consoleRegion ?? "cn-beijing";
|
|
748
|
-
const consoleSite = config.consoleSite ?? "domestic";
|
|
749
|
-
const consoleSwitchAgent = config.consoleSwitchAgent;
|
|
750
|
-
return consoleSwitchAgent != null ? {
|
|
751
|
-
consoleRegion,
|
|
752
|
-
consoleSite,
|
|
753
|
-
consoleSwitchAgent
|
|
754
|
-
} : {
|
|
755
|
-
consoleRegion,
|
|
756
|
-
consoleSite
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
function buildGatewayParams(api, data, switchAgent) {
|
|
760
|
-
return JSON.stringify({
|
|
761
|
-
Api: api,
|
|
762
|
-
V: "1.0",
|
|
763
|
-
Data: {
|
|
764
|
-
...data,
|
|
765
|
-
cornerstoneParam: {
|
|
766
|
-
protocol: "V2",
|
|
767
|
-
console: "ONE_CONSOLE",
|
|
768
|
-
productCode: "p_efm",
|
|
769
|
-
consoleSite: "BAILIAN_ALIYUN",
|
|
770
|
-
...switchAgent != null ? { switchAgent } : {},
|
|
771
|
-
...typeof data.cornerstoneParam === "object" && data.cornerstoneParam !== null ? data.cornerstoneParam : {}
|
|
772
|
-
}
|
|
773
|
-
}
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
/**
|
|
777
|
-
* Invoke a Bailian **console** OpenAPI via the CLI gateway (`/cli/api.json`).
|
|
778
|
-
* `token` is the console `access_token` (from `bl auth login --console`); when
|
|
779
|
-
* omitted the request is sent without an Authorization header, which works for
|
|
780
|
-
* public console APIs that don't require a login session.
|
|
781
|
-
*
|
|
782
|
-
* Gateway URL and action are resolved from `region + site` via {@link REGION_GATEWAYS}.
|
|
783
|
-
* Each parameter falls back to the corresponding config value, then to a hardcoded default.
|
|
784
|
-
*/
|
|
785
|
-
async function callConsoleGateway(config, token, { api, data }) {
|
|
786
|
-
const { consoleRegion: effectiveRegion, consoleSite: effectiveSite, consoleSwitchAgent: effectiveSwitchAgent } = effectiveConsoleGatewayConfig(config);
|
|
787
|
-
const resolved = resolveGateway(effectiveRegion, effectiveSite);
|
|
788
|
-
const gatewayBase = `https://${resolved.csGateway}`;
|
|
789
|
-
const action = resolved.action;
|
|
790
|
-
const params = buildGatewayParams(api, data, effectiveSwitchAgent);
|
|
791
|
-
const body = new URLSearchParams({
|
|
792
|
-
params,
|
|
793
|
-
region: effectiveRegion
|
|
794
|
-
});
|
|
795
|
-
const timeoutMs = config.timeout * 1e3;
|
|
796
|
-
const headers = {
|
|
797
|
-
Accept: "*/*",
|
|
798
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
799
|
-
};
|
|
800
|
-
if (token) headers.Authorization = `Bearer ${token}`;
|
|
801
|
-
const res = await fetch(`${gatewayBase}/cli/api.json?action=${action}&product=${GATEWAY_PRODUCT}&api=${encodeURIComponent(api)}`, {
|
|
802
|
-
method: "POST",
|
|
803
|
-
headers,
|
|
804
|
-
body: body.toString(),
|
|
805
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
806
|
-
});
|
|
807
|
-
if (!res.ok) {
|
|
808
|
-
const t = await res.text().catch(() => "");
|
|
809
|
-
throw new BailianError(`Console CLI gateway failed: HTTP ${res.status} ${res.statusText}`, ExitCode.GENERAL, t.slice(0, 500));
|
|
810
|
-
}
|
|
811
|
-
const json = await res.json();
|
|
812
|
-
const innerData = json.data;
|
|
813
|
-
if (innerData?.success === false && innerData.errorCode) {
|
|
814
|
-
const errorCode = String(innerData.errorCode);
|
|
815
|
-
const notLogined = errorCode.includes("NotLogined");
|
|
816
|
-
const errorMsg = typeof innerData.errorMsg === "string" ? innerData.errorMsg : void 0;
|
|
817
|
-
throw new BailianError(notLogined ? "Console session is not logged in or has expired." : `Console gateway error: ${errorCode}`, notLogined ? ExitCode.AUTH : ExitCode.GENERAL, notLogined ? "Run `bl auth login --console` to sign in or refresh your console session." : errorMsg && errorMsg !== errorCode ? errorMsg : void 0);
|
|
818
|
-
}
|
|
819
|
-
return json;
|
|
820
|
-
}
|
|
821
|
-
//#endregion
|
|
822
|
-
//#region src/console/models.ts
|
|
823
|
-
const MODEL_LIST_API = "zeldaHttp.dashscopeModel./zelda/api/v1/modelCenter/listFoundationModels";
|
|
824
|
-
async function fetchModelList(config, token, params = {}) {
|
|
825
|
-
const { pageNo = 1, pageSize = 50, name = "", providers = [], capabilities = [] } = params;
|
|
826
|
-
const result = await callConsoleGateway(config, token, {
|
|
827
|
-
api: MODEL_LIST_API,
|
|
828
|
-
data: { input: {
|
|
829
|
-
pageNo,
|
|
830
|
-
pageSize,
|
|
831
|
-
name,
|
|
832
|
-
providers,
|
|
833
|
-
inferenceProviders: [],
|
|
834
|
-
features: [],
|
|
835
|
-
group: true,
|
|
836
|
-
capabilities,
|
|
837
|
-
contextWindows: []
|
|
838
|
-
} }
|
|
839
|
-
});
|
|
840
|
-
const responseData = result?.data?.DataV2?.data ?? result?.data ?? {};
|
|
841
|
-
const total = responseData?.data?.total ?? responseData?.total ?? 0;
|
|
842
|
-
const groups = responseData?.data?.list ?? responseData?.list ?? [];
|
|
843
|
-
const models = [];
|
|
844
|
-
for (const group of groups) if (group.items?.length) for (const item of group.items) models.push(item);
|
|
845
|
-
else models.push(group);
|
|
846
|
-
return {
|
|
847
|
-
total,
|
|
848
|
-
models
|
|
849
|
-
};
|
|
850
|
-
}
|
|
851
|
-
//#endregion
|
|
852
|
-
//#region src/files/upload.ts
|
|
853
|
-
/**
|
|
854
|
-
* Upload local files to DashScope temporary OSS storage.
|
|
855
|
-
*
|
|
856
|
-
* Returns an `oss://` prefixed URL valid for 48 hours.
|
|
857
|
-
* When using this URL in API calls, the request MUST include:
|
|
858
|
-
* X-DashScope-OssResourceResolve: enable
|
|
859
|
-
*/
|
|
860
|
-
const UPLOAD_API = `${REGIONS.cn}/api/v1/uploads`;
|
|
861
|
-
/**
|
|
862
|
-
* Step 1: Fetch the upload policy (presigned credentials) from DashScope.
|
|
863
|
-
*/
|
|
864
|
-
async function getUploadPolicy(apiKey, model, signal) {
|
|
865
|
-
const url = `${UPLOAD_API}?action=getPolicy&model=${encodeURIComponent(model)}`;
|
|
866
|
-
const policySignal = combineWithTimeout(15e3, signal);
|
|
867
|
-
const res = await fetch(url, {
|
|
868
|
-
headers: {
|
|
869
|
-
Authorization: `Bearer ${apiKey}`,
|
|
870
|
-
"Content-Type": "application/json",
|
|
871
|
-
...trackingHeaders()
|
|
872
|
-
},
|
|
873
|
-
signal: policySignal.signal
|
|
874
|
-
}).finally(policySignal.cleanup);
|
|
875
|
-
if (!res.ok) {
|
|
876
|
-
const text = await res.text().catch(() => "");
|
|
877
|
-
throw new BailianError(`Failed to get upload policy (HTTP ${res.status}): ${text}`, ExitCode.GENERAL);
|
|
878
|
-
}
|
|
879
|
-
return (await res.json()).data;
|
|
880
|
-
}
|
|
881
|
-
/**
|
|
882
|
-
* Step 2: Upload the file to OSS using the policy.
|
|
883
|
-
*/
|
|
884
|
-
async function uploadToOSS(policy, filePath, signal) {
|
|
885
|
-
const fileName = basename(filePath);
|
|
886
|
-
const key = `${policy.upload_dir}/${fileName}`;
|
|
887
|
-
const fileData = readFileSync(filePath);
|
|
888
|
-
const form = new FormData();
|
|
889
|
-
form.append("OSSAccessKeyId", policy.oss_access_key_id);
|
|
890
|
-
form.append("Signature", policy.signature);
|
|
891
|
-
form.append("policy", policy.policy);
|
|
892
|
-
form.append("x-oss-object-acl", policy.x_oss_object_acl);
|
|
893
|
-
form.append("x-oss-forbid-overwrite", policy.x_oss_forbid_overwrite);
|
|
894
|
-
form.append("key", key);
|
|
895
|
-
form.append("success_action_status", "200");
|
|
896
|
-
form.append("file", new Blob([fileData]), fileName);
|
|
897
|
-
const uploadSignal = combineWithTimeout(12e4, signal);
|
|
898
|
-
const res = await fetch(policy.upload_host, {
|
|
899
|
-
method: "POST",
|
|
900
|
-
headers: { ...trackingHeaders() },
|
|
901
|
-
body: form,
|
|
902
|
-
signal: uploadSignal.signal
|
|
903
|
-
}).finally(uploadSignal.cleanup);
|
|
904
|
-
if (!res.ok) {
|
|
905
|
-
const text = await res.text().catch(() => "");
|
|
906
|
-
throw new BailianError(`Failed to upload file to OSS (HTTP ${res.status}): ${text}`, ExitCode.GENERAL);
|
|
907
|
-
}
|
|
908
|
-
return `oss://${key}`;
|
|
909
|
-
}
|
|
910
|
-
/**
|
|
911
|
-
* Upload a local file to DashScope temporary storage and return the oss:// URL.
|
|
912
|
-
* The URL is valid for 48 hours.
|
|
913
|
-
*/
|
|
914
|
-
async function uploadFile(opts) {
|
|
915
|
-
const { apiKey, model, filePath, signal } = opts;
|
|
916
|
-
if (!existsSync(filePath)) throw new BailianError(`File not found: ${filePath}`, ExitCode.USAGE);
|
|
917
|
-
if (!statSync(filePath).isFile()) throw new BailianError(`Not a file: ${filePath}`, ExitCode.USAGE);
|
|
918
|
-
return uploadToOSS(await getUploadPolicy(apiKey, model, signal), filePath, signal);
|
|
919
|
-
}
|
|
920
|
-
/**
|
|
921
|
-
* Check if a string looks like a local file path (not a URL).
|
|
922
|
-
*/
|
|
923
|
-
function isLocalFile(input) {
|
|
924
|
-
if (input.startsWith("http://") || input.startsWith("https://")) return false;
|
|
925
|
-
if (input.startsWith("oss://")) return false;
|
|
926
|
-
if (input.startsWith("data:")) return false;
|
|
927
|
-
return existsSync(input);
|
|
928
|
-
}
|
|
929
|
-
/**
|
|
930
|
-
* Resolve a file argument: if it's a local path, upload it and return the oss:// URL.
|
|
931
|
-
* If it's already a URL, return as-is.
|
|
932
|
-
*/
|
|
933
|
-
async function resolveFileUrl(input, apiKey, model, opts = {}) {
|
|
934
|
-
if (!isLocalFile(input)) return input;
|
|
935
|
-
return uploadFile({
|
|
936
|
-
apiKey,
|
|
937
|
-
model,
|
|
938
|
-
filePath: input,
|
|
939
|
-
signal: opts.signal
|
|
940
|
-
});
|
|
941
|
-
}
|
|
942
|
-
function combineWithTimeout(timeoutMs, parentSignal) {
|
|
943
|
-
const controller = new AbortController();
|
|
944
|
-
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
945
|
-
const abortFromParent = () => controller.abort(parentSignal?.reason);
|
|
946
|
-
const cleanup = () => {
|
|
947
|
-
clearTimeout(timeout);
|
|
948
|
-
parentSignal?.removeEventListener("abort", abortFromParent);
|
|
949
|
-
};
|
|
950
|
-
if (parentSignal?.aborted) abortFromParent();
|
|
951
|
-
else parentSignal?.addEventListener("abort", abortFromParent, { once: true });
|
|
952
|
-
controller.signal.addEventListener("abort", cleanup, { once: true });
|
|
953
|
-
return {
|
|
954
|
-
signal: controller.signal,
|
|
955
|
-
cleanup
|
|
956
|
-
};
|
|
957
|
-
}
|
|
958
|
-
//#endregion
|
|
959
|
-
//#region src/types/command.ts
|
|
960
|
-
function defineCommand(spec) {
|
|
961
|
-
return {
|
|
962
|
-
name: spec.name,
|
|
963
|
-
description: spec.description,
|
|
964
|
-
usage: spec.usage,
|
|
965
|
-
options: spec.options,
|
|
966
|
-
examples: spec.examples,
|
|
967
|
-
skipDefaultApiKeySetup: spec.skipDefaultApiKeySetup,
|
|
968
|
-
notes: spec.notes,
|
|
969
|
-
execute: (config, flags) => spec.run(config, flags)
|
|
970
|
-
};
|
|
971
|
-
}
|
|
972
|
-
/** Global flags shared by all commands — drives the parser's type resolution. */
|
|
973
|
-
const GLOBAL_OPTIONS = [
|
|
974
|
-
{
|
|
975
|
-
flag: "--api-key <key>",
|
|
976
|
-
description: "API key"
|
|
977
|
-
},
|
|
978
|
-
{
|
|
979
|
-
flag: "--base-url <url>",
|
|
980
|
-
description: "API base URL"
|
|
981
|
-
},
|
|
982
|
-
{
|
|
983
|
-
flag: "--output <format>",
|
|
984
|
-
description: "Output format: text, json"
|
|
985
|
-
},
|
|
986
|
-
{
|
|
987
|
-
flag: "--timeout <seconds>",
|
|
988
|
-
description: "Request timeout",
|
|
989
|
-
type: "number"
|
|
990
|
-
},
|
|
991
|
-
{
|
|
992
|
-
flag: "--quiet",
|
|
993
|
-
description: "Suppress non-essential output"
|
|
994
|
-
},
|
|
995
|
-
{
|
|
996
|
-
flag: "--verbose",
|
|
997
|
-
description: "Print HTTP request/response details"
|
|
998
|
-
},
|
|
999
|
-
{
|
|
1000
|
-
flag: "--no-color",
|
|
1001
|
-
description: "Disable ANSI colors"
|
|
1002
|
-
},
|
|
1003
|
-
{
|
|
1004
|
-
flag: "--dry-run",
|
|
1005
|
-
description: "Dry run mode"
|
|
1006
|
-
},
|
|
1007
|
-
{
|
|
1008
|
-
flag: "--non-interactive",
|
|
1009
|
-
description: "Disable interactive prompts"
|
|
1010
|
-
},
|
|
1011
|
-
{
|
|
1012
|
-
flag: "--concurrent <n>",
|
|
1013
|
-
description: "Run N parallel requests (default: 1)",
|
|
1014
|
-
type: "number"
|
|
1015
|
-
},
|
|
1016
|
-
{
|
|
1017
|
-
flag: "--console-region <region>",
|
|
1018
|
-
description: "Console gateway region (e.g. cn-beijing, ap-southeast-1)"
|
|
1019
|
-
},
|
|
1020
|
-
{
|
|
1021
|
-
flag: "--console-site <site>",
|
|
1022
|
-
description: "Console site: domestic, international"
|
|
1023
|
-
},
|
|
1024
|
-
{
|
|
1025
|
-
flag: "--console-switch-agent <uid>",
|
|
1026
|
-
description: "Switch agent UID for delegated access",
|
|
1027
|
-
type: "number"
|
|
1028
|
-
},
|
|
1029
|
-
{
|
|
1030
|
-
flag: "--help",
|
|
1031
|
-
description: "Show help"
|
|
1032
|
-
},
|
|
1033
|
-
{
|
|
1034
|
-
flag: "--version",
|
|
1035
|
-
description: "Print version"
|
|
1036
|
-
}
|
|
1037
|
-
];
|
|
1038
|
-
//#endregion
|
|
1039
|
-
//#region src/utils/filename.ts
|
|
1040
|
-
/**
|
|
1041
|
-
* 生成文件名前缀
|
|
1042
|
-
* @param prefix prompt的前10个字符
|
|
1043
|
-
* @param suffix timestamp
|
|
1044
|
-
* @returns
|
|
1045
|
-
*/
|
|
1046
|
-
function sanitizeFilenamePart(input, fallback) {
|
|
1047
|
-
return input.normalize("NFKC").replace(/[\\/:*?"<>|]/g, "_").replace(/\s+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "") || fallback;
|
|
1048
|
-
}
|
|
1049
|
-
function generateFilename(prefix, prompt) {
|
|
1050
|
-
return `${sanitizeFilenamePart(prefix || "image", "image")}_${sanitizeFilenamePart((prompt || "").substring(0, 20), "untitled")}_${Date.now()}`;
|
|
1051
|
-
}
|
|
1052
|
-
//#endregion
|
|
1053
|
-
//#region src/utils/output-dir.ts
|
|
1054
|
-
const DEFAULT_OUTPUT_DIR = () => join(homedir(), "bailian-output");
|
|
1055
|
-
/**
|
|
1056
|
-
* Resolve the output directory for generated files.
|
|
1057
|
-
*
|
|
1058
|
-
* Priority:
|
|
1059
|
-
* 1. User-specified dir (e.g. --out-dir flag)
|
|
1060
|
-
* 2. Config file output_dir
|
|
1061
|
-
* 3. Default: ~/bailian-output/
|
|
1062
|
-
*
|
|
1063
|
-
* Optionally appends a subdirectory (e.g. 'images', 'videos', 'speech').
|
|
1064
|
-
* Creates the directory if it doesn't exist.
|
|
1065
|
-
*/
|
|
1066
|
-
function resolveOutputDir(config, options) {
|
|
1067
|
-
const base = options?.flagDir || config.outputDir || DEFAULT_OUTPUT_DIR();
|
|
1068
|
-
const dir = options?.subDir ? join(base, options.subDir) : base;
|
|
1069
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
1070
|
-
return dir;
|
|
1071
|
-
}
|
|
1072
|
-
//#endregion
|
|
1073
|
-
//#region src/utils/schema.ts
|
|
1074
|
-
/**
|
|
1075
|
-
* Parse a CLI flag string (e.g. "--prompt <text>", "--stream") into
|
|
1076
|
-
* a parameter name and inferred type.
|
|
1077
|
-
*/
|
|
1078
|
-
function parseFlag(flag) {
|
|
1079
|
-
const match = flag.match(/^--([a-zA-Z0-9-]+)/);
|
|
1080
|
-
const kebabName = match ? match[1] : "";
|
|
1081
|
-
const name = kebabName.replace(/-([a-zA-Z0-9])/g, (_, c) => c.toUpperCase());
|
|
1082
|
-
let inferredType = "string";
|
|
1083
|
-
let isArray = false;
|
|
1084
|
-
if (!flag.includes("<") && !flag.includes("[")) inferredType = "boolean";
|
|
1085
|
-
else if (flag.includes("<n>") || flag.includes("<hz>") || flag.includes("<bps>") || flag.includes("<count>")) inferredType = "number";
|
|
1086
|
-
if (flag.toLowerCase().includes("repeatable")) isArray = true;
|
|
1087
|
-
return {
|
|
1088
|
-
name,
|
|
1089
|
-
kebabName,
|
|
1090
|
-
inferredType,
|
|
1091
|
-
isArray
|
|
1092
|
-
};
|
|
1093
|
-
}
|
|
1094
|
-
function generateToolSchema(cmd) {
|
|
1095
|
-
const schema = {
|
|
1096
|
-
name: `bailian_${cmd.name.replace(/ /g, "_")}`,
|
|
1097
|
-
description: cmd.description,
|
|
1098
|
-
input_schema: {
|
|
1099
|
-
type: "object",
|
|
1100
|
-
properties: {},
|
|
1101
|
-
required: []
|
|
1102
|
-
}
|
|
1103
|
-
};
|
|
1104
|
-
if (cmd.options) for (const opt of cmd.options) {
|
|
1105
|
-
const { name, inferredType, isArray } = parseFlag(opt.flag);
|
|
1106
|
-
if (!name) continue;
|
|
1107
|
-
const explicitType = opt.type;
|
|
1108
|
-
const effectiveType = isArray ? "array" : explicitType ?? inferredType;
|
|
1109
|
-
const propSchema = { description: opt.description };
|
|
1110
|
-
if (effectiveType === "array") {
|
|
1111
|
-
propSchema.type = "array";
|
|
1112
|
-
propSchema.items = { type: "string" };
|
|
1113
|
-
} else propSchema.type = effectiveType;
|
|
1114
|
-
const inputSchema = schema.input_schema;
|
|
1115
|
-
inputSchema.properties[name] = propSchema;
|
|
1116
|
-
if (opt.required) inputSchema.required.push(name);
|
|
1117
|
-
}
|
|
1118
|
-
return schema;
|
|
1119
|
-
}
|
|
1120
|
-
//#endregion
|
|
1121
|
-
//#region src/utils/env.ts
|
|
1122
|
-
/**
|
|
1123
|
-
* Environment detection utilities for bailian-cli.
|
|
1124
|
-
*
|
|
1125
|
-
* Used to determine whether the CLI is running in an interactive terminal
|
|
1126
|
-
* (human user) or in a non-interactive environment (CI, agent, pipe, etc.),
|
|
1127
|
-
* so commands can adjust their behavior accordingly.
|
|
1128
|
-
*/
|
|
1129
|
-
/**
|
|
1130
|
-
* Detects whether the current environment is interactive.
|
|
1131
|
-
*
|
|
1132
|
-
* Returns false when:
|
|
1133
|
-
* - stdout or stdin is not a TTY
|
|
1134
|
-
* - The --non-interactive flag was explicitly set
|
|
1135
|
-
* - The process is running in a known CI environment (CI env var present)
|
|
1136
|
-
*
|
|
1137
|
-
* Returns true when stdout and stdin are both TTYs and --non-interactive
|
|
1138
|
-
* was not passed.
|
|
1139
|
-
*/
|
|
1140
|
-
function isInteractive(options) {
|
|
1141
|
-
if (options?.nonInteractive === true) return false;
|
|
1142
|
-
if (process.env.CI) return false;
|
|
1143
|
-
return process.stdout.isTTY === true && process.stdin.isTTY === true;
|
|
1144
|
-
}
|
|
1145
|
-
/**
|
|
1146
|
-
* Detects whether the current process is running in a CI environment.
|
|
1147
|
-
*/
|
|
1148
|
-
function isCI() {
|
|
1149
|
-
return !!(process.env.CI || process.env.GITHUB_ACTIONS || process.env.GITLAB_CI || process.env.JENKINS_URL || process.env.TRAVIS || process.env.CIRCLECI);
|
|
1150
|
-
}
|
|
1151
|
-
//#endregion
|
|
1152
|
-
//#region src/utils/object.ts
|
|
1153
|
-
/**
|
|
1154
|
-
* Generic object-cleaning utilities.
|
|
1155
|
-
*/
|
|
1156
|
-
/**
|
|
1157
|
-
* Remove all keys whose value is `undefined` from a plain object (in-place).
|
|
1158
|
-
* Returns the same reference for chaining convenience.
|
|
1159
|
-
*
|
|
1160
|
-
* ```ts
|
|
1161
|
-
* const params = { a: 1, b: undefined };
|
|
1162
|
-
* stripUndefined(params); // { a: 1 }
|
|
1163
|
-
* ```
|
|
1164
|
-
*/
|
|
1165
|
-
function stripUndefined(obj) {
|
|
1166
|
-
for (const key of Object.keys(obj)) if (obj[key] === void 0) delete obj[key];
|
|
1167
|
-
return obj;
|
|
1168
|
-
}
|
|
1169
|
-
//#endregion
|
|
1170
|
-
//#region src/utils/boolean-flag.ts
|
|
1171
|
-
/** Parse true/false from CLI flags (e.g. `--watermark <bool>`). */
|
|
1172
|
-
function parseBooleanValue(value, label = "boolean") {
|
|
1173
|
-
if (typeof value === "boolean") return value;
|
|
1174
|
-
if (typeof value === "string") {
|
|
1175
|
-
const v = value.trim().toLowerCase();
|
|
1176
|
-
if (v === "true") return true;
|
|
1177
|
-
if (v === "false") return false;
|
|
1178
|
-
}
|
|
1179
|
-
throw new BailianError(`Invalid ${label} value "${String(value)}". Use true or false.`, ExitCode.USAGE);
|
|
1180
|
-
}
|
|
1181
|
-
function parseOptionalBooleanValue(value, label = "boolean") {
|
|
1182
|
-
if (value === void 0 || value === null) return void 0;
|
|
1183
|
-
return parseBooleanValue(value, label);
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* Resolve a tri-state boolean CLI flag (`--name <bool>`).
|
|
1187
|
-
* Returns `defaultWhenUnset` when the flag is omitted.
|
|
1188
|
-
*/
|
|
1189
|
-
function resolveBooleanFlag(flagValue, defaultWhenUnset, label = "boolean") {
|
|
1190
|
-
const fromFlag = parseOptionalBooleanValue(flagValue, label);
|
|
1191
|
-
if (fromFlag !== void 0) return fromFlag;
|
|
1192
|
-
return defaultWhenUnset;
|
|
1193
|
-
}
|
|
1194
|
-
/** Resolve `--watermark` flag; default true when unset. */
|
|
1195
|
-
function resolveWatermark(flagValue) {
|
|
1196
|
-
return parseOptionalBooleanValue(flagValue, "watermark") ?? true;
|
|
1197
|
-
}
|
|
1198
|
-
//#endregion
|
|
1199
|
-
//#region src/telemetry/event.ts
|
|
1200
|
-
function createTrackingEvent(opts) {
|
|
1201
|
-
const event = {
|
|
1202
|
-
command: opts.command,
|
|
1203
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1204
|
-
durationMs: opts.durationMs,
|
|
1205
|
-
success: opts.success,
|
|
1206
|
-
cliVersion: opts.cliVersion,
|
|
1207
|
-
nodeVersion: process.version,
|
|
1208
|
-
os: process.platform
|
|
1209
|
-
};
|
|
1210
|
-
if (opts.authMethod) event.authMethod = opts.authMethod;
|
|
1211
|
-
if (!opts.success && opts.error) {
|
|
1212
|
-
if (opts.error.message) event.errorMessage = opts.error.message;
|
|
1213
|
-
if (opts.error.httpStatus !== void 0) event.httpStatus = opts.error.httpStatus;
|
|
1214
|
-
if (opts.error.requestId) event.requestId = opts.error.requestId;
|
|
1215
|
-
}
|
|
1216
|
-
if (opts.params && Object.keys(opts.params).length > 0) event.params = opts.params;
|
|
1217
|
-
return event;
|
|
1218
|
-
}
|
|
1219
|
-
const AEM_TEXT_MAX = 500;
|
|
1220
|
-
function aemText(value) {
|
|
1221
|
-
if (value === void 0 || value === null) return void 0;
|
|
1222
|
-
const s = typeof value === "string" ? value : JSON.stringify(value);
|
|
1223
|
-
return s.length <= AEM_TEXT_MAX ? s : s.slice(0, AEM_TEXT_MAX);
|
|
1224
|
-
}
|
|
1225
|
-
function buildRemoteAemOptions(event) {
|
|
1226
|
-
const { command: _command, params, ...extFields } = event;
|
|
1227
|
-
const opts = {
|
|
1228
|
-
et: "EXP",
|
|
1229
|
-
ext: extFields,
|
|
1230
|
-
c1: params,
|
|
1231
|
-
c2: event.success ? "success" : "failure"
|
|
1232
|
-
};
|
|
1233
|
-
if (event.httpStatus !== void 0) opts.c3 = String(event.httpStatus);
|
|
1234
|
-
if (event.errorMessage) opts.c4 = aemText(event.errorMessage);
|
|
1235
|
-
if (event.requestId) opts.c5 = event.requestId;
|
|
1236
|
-
return opts;
|
|
1237
|
-
}
|
|
1238
|
-
//#endregion
|
|
1239
|
-
//#region src/telemetry/env.ts
|
|
1240
|
-
/**
|
|
1241
|
-
* 判断当前运行环境。任一条件为真即视为 dev,默认 prod。
|
|
1242
|
-
*
|
|
1243
|
-
* 1. NODE_ENV=development — Node 圈通用约定,测试同学/CI 可显式声明
|
|
1244
|
-
* 2. 当前模块文件路径不在 node_modules 里 — 自动识别从源码运行(pnpm dev /
|
|
1245
|
-
* npm link / 直接 node packages/cli/src/main.ts),避免开发者忘记设环境变量
|
|
1246
|
-
* 时仍把数据打到 prod
|
|
1247
|
-
*
|
|
1248
|
-
* 缓存结果,模块加载期算一次就行。
|
|
1249
|
-
*/
|
|
1250
|
-
let cachedEnv;
|
|
1251
|
-
function detectEnv() {
|
|
1252
|
-
if (cachedEnv) return cachedEnv;
|
|
1253
|
-
if (process.env.NODE_ENV === "development") {
|
|
1254
|
-
cachedEnv = "dev";
|
|
1255
|
-
return cachedEnv;
|
|
1256
|
-
}
|
|
1257
|
-
cachedEnv = import.meta.url.includes("/node_modules/") ? "prod" : "dev";
|
|
1258
|
-
return cachedEnv;
|
|
1259
|
-
}
|
|
1260
|
-
//#endregion
|
|
1261
|
-
//#region lib/remote-telemetry/tracker.js
|
|
1262
|
-
var require_tracker = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1263
|
-
module.exports = (function(e) {
|
|
1264
|
-
var t = {};
|
|
1265
|
-
function n(r) {
|
|
1266
|
-
if (t[r]) return t[r].exports;
|
|
1267
|
-
var o = t[r] = {
|
|
1268
|
-
i: r,
|
|
1269
|
-
l: !1,
|
|
1270
|
-
exports: {}
|
|
1271
|
-
};
|
|
1272
|
-
return e[r].call(o.exports, o, o.exports, n), o.l = !0, o.exports;
|
|
1273
|
-
}
|
|
1274
|
-
return n.m = e, n.c = t, n.d = function(e, t, r) {
|
|
1275
|
-
n.o(e, t) || Object.defineProperty(e, t, {
|
|
1276
|
-
enumerable: !0,
|
|
1277
|
-
get: r
|
|
1278
|
-
});
|
|
1279
|
-
}, n.r = function(e) {
|
|
1280
|
-
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 });
|
|
1281
|
-
}, n.t = function(e, t) {
|
|
1282
|
-
if (1 & t && (e = n(e)), 8 & t) return e;
|
|
1283
|
-
if (4 & t && "object" == typeof e && e && e.__esModule) return e;
|
|
1284
|
-
var r = Object.create(null);
|
|
1285
|
-
if (n.r(r), Object.defineProperty(r, "default", {
|
|
1286
|
-
enumerable: !0,
|
|
1287
|
-
value: e
|
|
1288
|
-
}), 2 & t && "string" != typeof e) for (var o in e) n.d(r, o, function(t) {
|
|
1289
|
-
return e[t];
|
|
1290
|
-
}.bind(null, o));
|
|
1291
|
-
return r;
|
|
1292
|
-
}, n.n = function(e) {
|
|
1293
|
-
var t = e && e.__esModule ? function() {
|
|
1294
|
-
return e.default;
|
|
1295
|
-
} : function() {
|
|
1296
|
-
return e;
|
|
1297
|
-
};
|
|
1298
|
-
return n.d(t, "a", t), t;
|
|
1299
|
-
}, n.o = function(e, t) {
|
|
1300
|
-
return Object.prototype.hasOwnProperty.call(e, t);
|
|
1301
|
-
}, n.p = "", n(n.s = 8);
|
|
1302
|
-
})([
|
|
1303
|
-
function(e, t) {
|
|
1304
|
-
e.exports = __require("os");
|
|
1305
|
-
},
|
|
1306
|
-
function(e, t) {
|
|
1307
|
-
e.exports = globalThis.fetch;
|
|
1308
|
-
},
|
|
1309
|
-
function(e, t, n) {
|
|
1310
|
-
"use strict";
|
|
1311
|
-
e.exports = n(6);
|
|
1312
|
-
},
|
|
1313
|
-
function(e, t) {
|
|
1314
|
-
e.exports = __require("dns");
|
|
1315
|
-
},
|
|
1316
|
-
function(e, t) {
|
|
1317
|
-
e.exports = __require("util");
|
|
1318
|
-
},
|
|
1319
|
-
function(e, t) {
|
|
1320
|
-
e.exports = __require("crypto");
|
|
1321
|
-
},
|
|
1322
|
-
function(e, t, n) {
|
|
1323
|
-
Object.defineProperty(t, Symbol.toStringTag, { value: "Module" });
|
|
1324
|
-
const r = n(7), o = (e, t) => {
|
|
1325
|
-
t.appName = "BaiduSpider", t.appVersion = e.value, t.deviceBrand = "Baidu", t.deviceType = "bot", t.platform = "other";
|
|
1326
|
-
}, i = (e, t) => {
|
|
1327
|
-
t.appName = "360 Spider", t.appVersion = e.value, t.deviceBrand = "360", t.deviceType = "bot", t.platform = "other";
|
|
1328
|
-
}, a = (e, t) => {
|
|
1329
|
-
t.appName = "BingBot", t.appVersion = e.value, t.deviceBrand = "Microsoft", t.deviceType = "bot", t.platform = "other";
|
|
1330
|
-
}, u = (e, t) => {
|
|
1331
|
-
t.appName = "Googlebot", t.appVersion = e.value, t.deviceBrand = "Google", t.deviceType = "bot", t.platform = "other";
|
|
1332
|
-
}, p = (e, t) => {
|
|
1333
|
-
t.appName = "YandexBot", t.appVersion = e.value, t.deviceBrand = "Yandex", t.deviceType = "bot", t.platform = "other";
|
|
1334
|
-
}, l = (e, t) => {
|
|
1335
|
-
"Sogou web spider" === e.getPreviousNTokens(3) && (t.deviceBrand = "Sogou.com", t.appName = "SogouSpider"), t.appVersion = e.value, t.deviceType = "bot";
|
|
1336
|
-
}, s = (e, t) => {
|
|
1337
|
-
t.appName = "DataproviderBot", t.appVersion = e.value, t.deviceBrand = "Dataprovider.com", t.deviceType = "bot", t.platform = "other";
|
|
1338
|
-
}, c = (e, t) => {
|
|
1339
|
-
t.appName = "AhrefsBot", t.appVersion = e.value, t.deviceBrand = "Ahrefs", t.deviceType = "bot", t.platform = "other";
|
|
1340
|
-
}, d = (e, t) => {
|
|
1341
|
-
t.appName = "BitSightBot", t.appVersion = e.value, t.deviceBrand = "Bitsight", t.deviceType = "bot", t.platform = "other";
|
|
1342
|
-
}, f = (e, t) => {
|
|
1343
|
-
t.appName = "oBot", t.appVersion = e.value, t.deviceBrand = "IBM", t.deviceType = "bot", t.platform = "other";
|
|
1344
|
-
}, v = (e, t) => {
|
|
1345
|
-
t.appName = "Cincraw", t.appVersion = e.value, t.deviceBrand = "CINC", t.deviceType = "bot", t.platform = "other";
|
|
1346
|
-
}, g = (e, t) => {
|
|
1347
|
-
t.appName = "DingTalkBot", t.appVersion = e.value, t.deviceBrand = "Alibaba", t.deviceType = "bot", t.platform = "other";
|
|
1348
|
-
}, h = (e, t) => {
|
|
1349
|
-
t.appName = "YisouSpider", t.appVersion = e.value, t.deviceBrand = "Alibaba", t.deviceType = "bot", t.platform = "other";
|
|
1350
|
-
}, m = (e, t) => {
|
|
1351
|
-
t.appName = "ByteSpider", t.appVersion = e.value, t.deviceBrand = "ByteDance", t.deviceType = "bot", t.platform = "other";
|
|
1352
|
-
}, b = (e, t) => {
|
|
1353
|
-
t.appName = "HeadlineCrawler", t.appVersion = e.value, t.deviceBrand = "Headline.com", t.deviceType = "bot", t.platform = "other";
|
|
1354
|
-
}, y = (e, t) => {
|
|
1355
|
-
t.appName = "BitDiscoveryBot", t.appVersion = e.value, t.deviceBrand = "Tenable", t.deviceType = "bot", t.platform = "other";
|
|
1356
|
-
}, _ = (e, t) => {
|
|
1357
|
-
"Screaming Frog SEO Spider" === e.getPreviousNTokens(4) && (t.deviceBrand = "Screaming Frog", t.appName = "Screaming Frog"), t.appVersion = e.value, t.deviceType = "bot";
|
|
1358
|
-
}, B = (e, t) => {
|
|
1359
|
-
t.appName = "Ai2Bot", t.appVersion = e.value, t.deviceBrand = "Ai2", t.deviceType = "bot", t.platform = "other";
|
|
1360
|
-
}, S = (e, t) => {
|
|
1361
|
-
t.appName = "DianjingAdSpider", t.appVersion = e.value, t.deviceBrand = "Dianjing", t.deviceType = "bot", t.platform = "other";
|
|
1362
|
-
}, T = (e, t) => {
|
|
1363
|
-
t.appName = "BaiduSpider", t.appVersion = e.value, t.deviceBrand = "Baidu", t.deviceType = "bot", t.platform = "other";
|
|
1364
|
-
}, j = (e, t) => {
|
|
1365
|
-
t.appName = "360 Spider", t.appVersion = e.value, t.deviceBrand = "360", t.deviceType = "bot", t.platform = "other";
|
|
1366
|
-
}, N = (e, t) => {
|
|
1367
|
-
t.appName = "BingBot", t.appVersion = e.value, t.deviceBrand = "Microsoft", t.deviceType = "bot", t.platform = "other";
|
|
1368
|
-
}, w = (e, t) => {
|
|
1369
|
-
t.appName = "Googlebot", t.appVersion = e.value, t.deviceBrand = "Google", t.deviceType = "bot", t.platform = "other";
|
|
1370
|
-
}, O = (e, t) => {
|
|
1371
|
-
t.appName = "YandexBot", t.appVersion = e.value, t.deviceBrand = "Yandex", t.deviceType = "bot", t.platform = "other";
|
|
1372
|
-
}, V = (e, t) => {
|
|
1373
|
-
"Sogou web spider" === e.getPreviousNTokens(3) && (t.deviceBrand = "Sogou.com", t.appName = "SogouSpider"), t.appVersion = e.value, t.deviceType = "bot";
|
|
1374
|
-
}, A = (e, t) => {
|
|
1375
|
-
t.appName = "DataproviderBot", t.appVersion = e.value, t.deviceBrand = "Dataprovider.com", t.deviceType = "bot", t.platform = "other";
|
|
1376
|
-
}, D = (e, t) => {
|
|
1377
|
-
t.appName = "AhrefsBot", t.appVersion = e.value, t.deviceBrand = "Ahrefs", t.deviceType = "bot", t.platform = "other";
|
|
1378
|
-
}, k = (e, t) => {
|
|
1379
|
-
t.appName = "BitSightBot", t.appVersion = e.value, t.deviceBrand = "Bitsight", t.deviceType = "bot", t.platform = "other";
|
|
1380
|
-
}, P = (e, t) => {
|
|
1381
|
-
t.appName = "oBot", t.appVersion = e.value, t.deviceBrand = "IBM", t.deviceType = "bot", t.platform = "other";
|
|
1382
|
-
}, C = (e, t) => {
|
|
1383
|
-
t.appName = "Cincraw", t.appVersion = e.value, t.deviceBrand = "CINC", t.deviceType = "bot", t.platform = "other";
|
|
1384
|
-
}, E = (e, t) => {
|
|
1385
|
-
t.appName = "DingTalkBot", t.appVersion = e.value, t.deviceBrand = "Alibaba", t.deviceType = "bot", t.platform = "other";
|
|
1386
|
-
}, x = (e, t) => {
|
|
1387
|
-
t.appName = "YisouSpider", t.appVersion = e.value, t.deviceBrand = "Alibaba", t.deviceType = "bot", t.platform = "other";
|
|
1388
|
-
}, M = (e, t) => {
|
|
1389
|
-
t.appName = "ByteSpider", t.appVersion = e.value, t.deviceBrand = "ByteDance", t.deviceType = "bot", t.platform = "other";
|
|
1390
|
-
}, q = (e, t) => {
|
|
1391
|
-
t.appName = "HeadlineCrawler", t.appVersion = e.value, t.deviceBrand = "Headline.com", t.deviceType = "bot", t.platform = "other";
|
|
1392
|
-
}, I = (e, t) => {
|
|
1393
|
-
t.appName = "BitDiscoveryBot", t.appVersion = e.value, t.deviceBrand = "Tenable", t.deviceType = "bot", t.platform = "other";
|
|
1394
|
-
}, H = (e, t) => {
|
|
1395
|
-
"Screaming Frog SEO Spider" === e.getPreviousNTokens(4) && (t.deviceBrand = "Screaming Frog", t.appName = "Screaming Frog"), t.appVersion = e.value, t.deviceType = "bot";
|
|
1396
|
-
}, U = (e, t) => {
|
|
1397
|
-
t.appName = "Ai2Bot", t.appVersion = e.value, t.deviceBrand = "Ai2", t.deviceType = "bot", t.platform = "other";
|
|
1398
|
-
}, L = (e, t) => {
|
|
1399
|
-
t.appName = "DianjingAdSpider", t.appVersion = e.value, t.deviceBrand = "Dianjing", t.deviceType = "bot", t.platform = "other";
|
|
1400
|
-
}, Q = /* @__PURE__ */ new Map(), R = /* @__PURE__ */ new Map();
|
|
1401
|
-
Q.set("Baiduspider-render", o), Q.set("Baiduspider+", o), Q.set("Baiduspider-image+", o), Q.set("360Spider", i), Q.set("360Spider-Image", i), Q.set("bingbot", a), Q.set("Googlebot", u), Q.set("YandexRenderResourcesBot", p), Q.set("spider", l), Q.set("Dataprovider.com", s), Q.set("AhrefsBot", c), Q.set("BitSightBot", d), Q.set("oBot", f), Q.set("Cincraw", v), Q.set("DingTalkBot-LinkService", g), Q.set("YisouSpider", h), Q.set("Bytespider", m), Q.set("ev-crawler", b), Q.set("bitdiscovery", y), Q.set("Spider", _), Q.set("Ai2Bot-Dolma", B), Q.set("dianjing_ad_spider", S), R.set("Baiduspider-render", T), R.set("Baiduspider+", T), R.set("Baiduspider-image+", T), R.set("360Spider", j), R.set("360Spider-Image", j), R.set("bingbot", N), R.set("Googlebot", w), R.set("YandexRenderResourcesBot", O), R.set("spider", V), R.set("Dataprovider.com", A), R.set("AhrefsBot", D), R.set("BitSightBot", k), R.set("oBot", P), R.set("Cincraw", C), R.set("DingTalkBot-LinkService", E), R.set("YisouSpider", x), R.set("Bytespider", M), R.set("ev-crawler", q), R.set("bitdiscovery", I), R.set("Spider", H), R.set("Ai2Bot-Dolma", U), R.set("dianjing_ad_spider", L);
|
|
1402
|
-
const F = {
|
|
1403
|
-
productHandlerMap: Q,
|
|
1404
|
-
commentHandlerMap: R,
|
|
1405
|
-
getSpecialProductHandler: () => null,
|
|
1406
|
-
getSpecialCommentHandler: () => null,
|
|
1407
|
-
getDefaultModelHandler: () => null
|
|
1408
|
-
};
|
|
1409
|
-
t.isBot = function(e) {
|
|
1410
|
-
const t = r.createUAInfo();
|
|
1411
|
-
return r.runTask(e, t, F), "bot" === t.deviceType;
|
|
1412
|
-
};
|
|
1413
|
-
},
|
|
1414
|
-
function(e, t) {
|
|
1415
|
-
function n(e) {
|
|
1416
|
-
const t = [], n = {
|
|
1417
|
-
parent: e,
|
|
1418
|
-
tokens: t,
|
|
1419
|
-
get firstToken() {
|
|
1420
|
-
return 0 === t.length ? null : t[0];
|
|
1421
|
-
},
|
|
1422
|
-
getNewToken(r) {
|
|
1423
|
-
const o = (function() {
|
|
1424
|
-
const e = [], t = [], n = [];
|
|
1425
|
-
let r = null, o = null, i = null, a = !0, u = !0, p = !0, l = null;
|
|
1426
|
-
const s = {
|
|
1427
|
-
get key() {
|
|
1428
|
-
return a && (r = e.join(""), a = !1), r;
|
|
1429
|
-
},
|
|
1430
|
-
get value() {
|
|
1431
|
-
return u && (o = t.join(""), u = !1), o;
|
|
1432
|
-
},
|
|
1433
|
-
get originValue() {
|
|
1434
|
-
return p && (i = n.join(""), p = !1), i;
|
|
1435
|
-
},
|
|
1436
|
-
previousToken: null,
|
|
1437
|
-
properties: null,
|
|
1438
|
-
appendKey(t) {
|
|
1439
|
-
e.push(t), a = !0;
|
|
1440
|
-
},
|
|
1441
|
-
appendValue(e) {
|
|
1442
|
-
t.push("_" === e ? "." : e), n.push(e), u = !0, p = !0, l = null;
|
|
1443
|
-
},
|
|
1444
|
-
getSplitValue(e) {
|
|
1445
|
-
if (null === l) {
|
|
1446
|
-
const e = s.value;
|
|
1447
|
-
l = "" === e ? [] : e.split("/");
|
|
1448
|
-
}
|
|
1449
|
-
return e >= 0 && e < l.length ? l[e] : null;
|
|
1450
|
-
},
|
|
1451
|
-
getPreviousNTokens(e) {
|
|
1452
|
-
const t = [];
|
|
1453
|
-
let n = s;
|
|
1454
|
-
for (let r = 0; r < e; r++) {
|
|
1455
|
-
if (null == n) return null;
|
|
1456
|
-
t.unshift(n.key), n = n.previousToken;
|
|
1457
|
-
}
|
|
1458
|
-
return t.join(" ");
|
|
1459
|
-
}
|
|
1460
|
-
};
|
|
1461
|
-
return s;
|
|
1462
|
-
})();
|
|
1463
|
-
return t.push(o), o.previousToken = void 0 !== r ? r : t.length > 1 ? t[t.length - 2] : null, e && (e.properties = n), o;
|
|
1464
|
-
},
|
|
1465
|
-
getLastToken: () => 0 === t.length ? null : t[t.length - 1],
|
|
1466
|
-
getFirstToken: () => 0 === t.length ? null : t[0],
|
|
1467
|
-
isEmpty: () => 0 === t.length
|
|
1468
|
-
};
|
|
1469
|
-
return n;
|
|
1470
|
-
}
|
|
1471
|
-
function r() {
|
|
1472
|
-
return {
|
|
1473
|
-
appName: null,
|
|
1474
|
-
appVersion: null,
|
|
1475
|
-
browserName: null,
|
|
1476
|
-
browserVersion: null,
|
|
1477
|
-
engineName: null,
|
|
1478
|
-
engineVersion: null,
|
|
1479
|
-
deviceBrand: null,
|
|
1480
|
-
deviceModel: null,
|
|
1481
|
-
deviceType: "mobile",
|
|
1482
|
-
osName: null,
|
|
1483
|
-
osVersion: null,
|
|
1484
|
-
platform: "web",
|
|
1485
|
-
tokenGroup: n(null)
|
|
1486
|
-
};
|
|
1487
|
-
}
|
|
1488
|
-
const o = new Set(" ;,\"'".split("")), i = new Set("/=:".split("")), a = new Set([
|
|
1489
|
-
"Mozilla",
|
|
1490
|
-
"AppleWebKit",
|
|
1491
|
-
"Safari",
|
|
1492
|
-
"Opera",
|
|
1493
|
-
"Dalvik",
|
|
1494
|
-
"com.ss.android.ugc.aweme"
|
|
1495
|
-
]);
|
|
1496
|
-
function u(e) {
|
|
1497
|
-
return 1 === e.length && o.has(e);
|
|
1498
|
-
}
|
|
1499
|
-
function p(e) {
|
|
1500
|
-
return 1 === e.length && i.has(e);
|
|
1501
|
-
}
|
|
1502
|
-
function l(e, t, n, r) {
|
|
1503
|
-
if (null == e) return;
|
|
1504
|
-
const o = t.parent, i = e.key;
|
|
1505
|
-
let u = null;
|
|
1506
|
-
if (null != o) {
|
|
1507
|
-
const e = o.key;
|
|
1508
|
-
var p, l;
|
|
1509
|
-
if (a.has(e)) u = null !== (p = r.commentHandlerMap.get(i)) && void 0 !== p ? p : null, u ??= r.getSpecialCommentHandler(i), null == u && i.endsWith(" Build") && (u = r.getDefaultModelHandler());
|
|
1510
|
-
else u = null !== (l = r.productHandlerMap.get(i)) && void 0 !== l ? l : r.getSpecialProductHandler(i);
|
|
1511
|
-
} else {
|
|
1512
|
-
var s;
|
|
1513
|
-
u = null !== (s = r.productHandlerMap.get(i)) && void 0 !== s ? s : r.getSpecialProductHandler(i);
|
|
1514
|
-
}
|
|
1515
|
-
if (null != u) try {
|
|
1516
|
-
u(e, n);
|
|
1517
|
-
} catch (e) {}
|
|
1518
|
-
}
|
|
1519
|
-
function s(e, t, r) {
|
|
1520
|
-
if (null == e) throw new Error("input can not be null");
|
|
1521
|
-
return (function e(t, r, o, i, a) {
|
|
1522
|
-
let s, c = null, d = null, f = !1;
|
|
1523
|
-
const v = t.length;
|
|
1524
|
-
let g = r > 0 ? t[r - 1] : "\0";
|
|
1525
|
-
for (s = r; s < v; s++) {
|
|
1526
|
-
const h = t[s];
|
|
1527
|
-
if (u(h)) {
|
|
1528
|
-
const e = "\0" !== g && u(g);
|
|
1529
|
-
if (!f && r > 0 && " " === h && !e) {
|
|
1530
|
-
const e = s + 1;
|
|
1531
|
-
if (e < v) {
|
|
1532
|
-
const n = t[e];
|
|
1533
|
-
/\d/.test(n) || "-" === n ? f = !0 : d?.appendKey(h);
|
|
1534
|
-
} else d?.appendKey(h);
|
|
1535
|
-
} else null != d && (c = d, d = null);
|
|
1536
|
-
g = h;
|
|
1537
|
-
} else if ("(" === h) {
|
|
1538
|
-
if ("(" === g) {
|
|
1539
|
-
g = h;
|
|
1540
|
-
continue;
|
|
1541
|
-
}
|
|
1542
|
-
const r = s;
|
|
1543
|
-
s = e(t, s + 1, n(o.getLastToken()), i, a), null != d && (c = d, d = null), g = t[r];
|
|
1544
|
-
} else {
|
|
1545
|
-
if (")" === h) {
|
|
1546
|
-
if (0 === r) {
|
|
1547
|
-
g = h;
|
|
1548
|
-
continue;
|
|
1549
|
-
}
|
|
1550
|
-
break;
|
|
1551
|
-
}
|
|
1552
|
-
d ?? (l(o.getLastToken(), o, i, a), d = o.getNewToken(c), f = !1), p(h) ? (f && d.appendValue(h), f = !0) : f ? d.appendValue(h) : d.appendKey(h), g = h;
|
|
1553
|
-
}
|
|
1554
|
-
}
|
|
1555
|
-
return l(o.getLastToken(), o, i, a), s;
|
|
1556
|
-
})(e, 0, t.tokenGroup, t, r), t;
|
|
1557
|
-
}
|
|
1558
|
-
Object.defineProperty(t, "DEFAULT_MODEL_HANDLER_KEY", {
|
|
1559
|
-
enumerable: !0,
|
|
1560
|
-
get: function() {
|
|
1561
|
-
return "DEFAULT_MODEL_HANDLER";
|
|
1562
|
-
}
|
|
1563
|
-
}), Object.defineProperty(t, "createUAInfo", {
|
|
1564
|
-
enumerable: !0,
|
|
1565
|
-
get: function() {
|
|
1566
|
-
return r;
|
|
1567
|
-
}
|
|
1568
|
-
}), Object.defineProperty(t, "runTask", {
|
|
1569
|
-
enumerable: !0,
|
|
1570
|
-
get: function() {
|
|
1571
|
-
return s;
|
|
1572
|
-
}
|
|
1573
|
-
});
|
|
1574
|
-
},
|
|
1575
|
-
function(e, t, n) {
|
|
1576
|
-
"use strict";
|
|
1577
|
-
n.r(t);
|
|
1578
|
-
var r = n(0), o = n.n(r), i = n(1), a = n.n(i);
|
|
1579
|
-
n(2);
|
|
1580
|
-
function u() {
|
|
1581
|
-
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : 20, t = arguments.length > 1 ? arguments[1] : void 0;
|
|
1582
|
-
return t = t || "", e ? u(--e, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(60 * Math.random())) + t) : t;
|
|
1583
|
-
}
|
|
1584
|
-
function p(e, t) {
|
|
1585
|
-
for (var n in t) e[n] = t[n];
|
|
1586
|
-
return e;
|
|
1587
|
-
}
|
|
1588
|
-
function l(e) {
|
|
1589
|
-
return "[object Object]" === Object.prototype.toString.call(e);
|
|
1590
|
-
}
|
|
1591
|
-
function s(e) {
|
|
1592
|
-
return "undefined" != typeof Promise && e instanceof Promise;
|
|
1593
|
-
}
|
|
1594
|
-
var c = Object.freeze({ __aesBeforeSkip: 1 }), d = function(e) {
|
|
1595
|
-
var t = Object.prototype.toString.call(e);
|
|
1596
|
-
if ("[object String]" === t && e || "[object Number]" === t || "[object Boolean]" === t) return e;
|
|
1597
|
-
if ("[object Object]" === t || "[object Array]" === t) try {
|
|
1598
|
-
return JSON.stringify(e);
|
|
1599
|
-
} catch (e) {}
|
|
1600
|
-
}, f = function(e) {
|
|
1601
|
-
var t = {};
|
|
1602
|
-
for (var n in e) {
|
|
1603
|
-
var r = e[n];
|
|
1604
|
-
void 0 !== r && (t[n] = d(r));
|
|
1605
|
-
}
|
|
1606
|
-
return t;
|
|
1607
|
-
}, v = function(e) {
|
|
1608
|
-
var t = [];
|
|
1609
|
-
for (var n in e) {
|
|
1610
|
-
var r = d(e[n]);
|
|
1611
|
-
void 0 !== r && t.push("".concat(n, "=").concat(encodeURIComponent(r)));
|
|
1612
|
-
}
|
|
1613
|
-
return t.join("&");
|
|
1614
|
-
};
|
|
1615
|
-
function g(e) {
|
|
1616
|
-
return (e.requiredFields || []).concat(["pid"]).some(function(t) {
|
|
1617
|
-
return void 0 === e[t];
|
|
1618
|
-
});
|
|
1619
|
-
}
|
|
1620
|
-
function h() {
|
|
1621
|
-
var e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : "", t = arguments.length > 1 ? arguments[1] : void 0;
|
|
1622
|
-
"undefined" != typeof console && console.warn("日志解析报错,埋点将被丢弃 => ".concat(e), t);
|
|
1623
|
-
}
|
|
1624
|
-
var m = "AEM_TRACKER_UNIQUE_PVID", b = "undefined" != typeof globalThis && globalThis ? globalThis : "undefined" != typeof window && window ? window : "undefined" != typeof global && global ? global : "undefined" != typeof self && self ? self : (console.error("Unable to locate global object in current environment"), {});
|
|
1625
|
-
function y(e) {
|
|
1626
|
-
this._queue = [], this._reqQueue = [], this._plugins = {}, this._subscribers = { onConfigUpdated: [] }, this._timeout = 0, this._config = {
|
|
1627
|
-
sdk_version: "3.3.18",
|
|
1628
|
-
set pv_id(e) {
|
|
1629
|
-
b[m] = e;
|
|
1630
|
-
},
|
|
1631
|
-
get pv_id() {
|
|
1632
|
-
return b[m] || (b[m] = u()), b[m];
|
|
1633
|
-
},
|
|
1634
|
-
timezone_offset: (/* @__PURE__ */ new Date()).getTimezoneOffset()
|
|
1635
|
-
}, e && (this._config = p(this._config, e));
|
|
1636
|
-
}
|
|
1637
|
-
y.prototype = {
|
|
1638
|
-
constructor: y,
|
|
1639
|
-
_sendAll: function() {
|
|
1640
|
-
if (this._timeout && (clearTimeout(this._timeout), this._timeout = 0), this._queue.length) {
|
|
1641
|
-
var e, t = this._config.maxUrlLength || 3e4, n = this._getSendConfig();
|
|
1642
|
-
try {
|
|
1643
|
-
e = this._processData(this._queue, n);
|
|
1644
|
-
} catch (e) {}
|
|
1645
|
-
if (e && e.length < t) return this._queue = [], void this.send(e);
|
|
1646
|
-
for (var r, o = []; this._queue.length;) {
|
|
1647
|
-
o.push(this._queue.shift());
|
|
1648
|
-
try {
|
|
1649
|
-
r = this._processData(o, n);
|
|
1650
|
-
} catch (e) {
|
|
1651
|
-
var i = o.pop();
|
|
1652
|
-
h(e.message, i);
|
|
1653
|
-
continue;
|
|
1654
|
-
}
|
|
1655
|
-
if (r.length > t) {
|
|
1656
|
-
o.length > 1 && (this._queue.unshift(o.pop()), r = this._processData(o, n));
|
|
1657
|
-
break;
|
|
1658
|
-
}
|
|
1659
|
-
}
|
|
1660
|
-
r && this.send(r), this._queue.length && this._sendAll();
|
|
1661
|
-
}
|
|
1662
|
-
},
|
|
1663
|
-
_send: function(e, t) {
|
|
1664
|
-
var n = this;
|
|
1665
|
-
if (!1 === t) {
|
|
1666
|
-
var r;
|
|
1667
|
-
try {
|
|
1668
|
-
r = this._processData([e]);
|
|
1669
|
-
} catch (t) {
|
|
1670
|
-
h(t.message, e);
|
|
1671
|
-
}
|
|
1672
|
-
r && this.send(r);
|
|
1673
|
-
} else {
|
|
1674
|
-
this._queue.push(e);
|
|
1675
|
-
var o = this._config.mergeRequestInterval || 500;
|
|
1676
|
-
this._timeout || (this._timeout = setTimeout(function() {
|
|
1677
|
-
n._sendAll();
|
|
1678
|
-
}, o));
|
|
1679
|
-
}
|
|
1680
|
-
},
|
|
1681
|
-
_getSendConfig: function() {
|
|
1682
|
-
var e = {}, t = this._config;
|
|
1683
|
-
for (var n in t) "requiredFields" !== n && "maxUrlLength" !== n && "queueGlobalName" !== n && "debug" !== n && "excludeCrawlers" !== n && "collectClientHints" !== n && 0 !== n.indexOf("plugin") && "" !== t[n] && null !== t[n] && void 0 !== t[n] && (e[n] = d(t[n]));
|
|
1684
|
-
return e;
|
|
1685
|
-
},
|
|
1686
|
-
_processData: function(e, t) {
|
|
1687
|
-
t = t || this._getSendConfig();
|
|
1688
|
-
var n = v(t);
|
|
1689
|
-
return n += "&msg=" + encodeURIComponent(e.map(function(e) {
|
|
1690
|
-
return v(e);
|
|
1691
|
-
}).join("|"));
|
|
1692
|
-
},
|
|
1693
|
-
setConfig: function(e, t) {
|
|
1694
|
-
var n = this, r = {};
|
|
1695
|
-
void 0 !== t ? r[e] = t : r = e;
|
|
1696
|
-
var o = !(function e(t, n) {
|
|
1697
|
-
if (void 0 === t || void 0 === n) return !1;
|
|
1698
|
-
if (!l(t) || !l(n)) return !1;
|
|
1699
|
-
for (var r in t) if (l(t[r])) {
|
|
1700
|
-
if (!e(t[r], n[r])) return !1;
|
|
1701
|
-
} else if (t[r] !== n[r]) return !1;
|
|
1702
|
-
return !0;
|
|
1703
|
-
})(r, this._config), i = function() {
|
|
1704
|
-
if (o) {
|
|
1705
|
-
for (var e in r) l(r[e]) ? n._config[e] = p(n._config[e] || {}, r[e]) : n._config[e] = r[e];
|
|
1706
|
-
n._execSubscribe("onConfigUpdated", [r, n._config]);
|
|
1707
|
-
}
|
|
1708
|
-
};
|
|
1709
|
-
this._reqQueue.length ? (i(), g(this._config) || (this._reqQueue.forEach(function(e) {
|
|
1710
|
-
n._send.apply(n, e);
|
|
1711
|
-
}), this._reqQueue = [])) : (o && this._sendAll(), i());
|
|
1712
|
-
},
|
|
1713
|
-
getConfig: function(e) {
|
|
1714
|
-
return e ? this._config[e] : this._config;
|
|
1715
|
-
},
|
|
1716
|
-
updatePVID: (function(e, t) {
|
|
1717
|
-
if ("function" != typeof e) throw new TypeError("Expected a function");
|
|
1718
|
-
t = "number" == typeof t && t >= 0 ? t : 100;
|
|
1719
|
-
var n = null;
|
|
1720
|
-
return function() {
|
|
1721
|
-
if (null === n) {
|
|
1722
|
-
var r = this, o = Array.prototype.slice.call(arguments);
|
|
1723
|
-
n = setTimeout(function() {
|
|
1724
|
-
n = null;
|
|
1725
|
-
}, t), e.apply(r, o);
|
|
1726
|
-
}
|
|
1727
|
-
};
|
|
1728
|
-
})(function() {
|
|
1729
|
-
b[m] = u();
|
|
1730
|
-
}, 200),
|
|
1731
|
-
log: function(e) {
|
|
1732
|
-
var t = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : {}, n = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : {};
|
|
1733
|
-
e && (t.ts = t.ts || (/* @__PURE__ */ new Date()).getTime(), t.type = e, this._print("log", e, t), t = f(t), g(this._config) ? this._reqQueue.length < 1e3 && this._reqQueue.push([t, n.combo]) : this._send(t, n.combo));
|
|
1734
|
-
},
|
|
1735
|
-
before: function(e, t) {
|
|
1736
|
-
var n = this;
|
|
1737
|
-
return function() {
|
|
1738
|
-
var r = arguments, o = t.apply(n, r);
|
|
1739
|
-
o !== c && (s(o) ? o.then(function(t) {
|
|
1740
|
-
t !== c && e.apply(n, t || r);
|
|
1741
|
-
}) : e.apply(n, o || r));
|
|
1742
|
-
};
|
|
1743
|
-
},
|
|
1744
|
-
after: function(e, t) {
|
|
1745
|
-
var n = this;
|
|
1746
|
-
return function() {
|
|
1747
|
-
var r = arguments;
|
|
1748
|
-
e.apply(n, r), t.apply(n, r);
|
|
1749
|
-
};
|
|
1750
|
-
},
|
|
1751
|
-
use: function(e, t) {
|
|
1752
|
-
var n = this;
|
|
1753
|
-
return "[object Array]" === Object.prototype.toString.call(e) ? e.map(function(e) {
|
|
1754
|
-
if ("[object Array]" === Object.prototype.toString.call(e)) {
|
|
1755
|
-
var t = e[0], r = e[1];
|
|
1756
|
-
return n._plugins[t] || (n._plugins[t] = new t(n, r));
|
|
1757
|
-
}
|
|
1758
|
-
return n._plugins[e] || (n._plugins[e] = new e(n));
|
|
1759
|
-
}) : this._plugins[e] || (this._plugins[e] = new e(this, t));
|
|
1760
|
-
},
|
|
1761
|
-
_print: function() {
|
|
1762
|
-
this._config.debug && "undefined" != typeof console && console.log.apply(console, arguments);
|
|
1763
|
-
},
|
|
1764
|
-
onConfigUpdated: function(e) {
|
|
1765
|
-
this._subscribers.onConfigUpdated && this._subscribers.onConfigUpdated.push(e);
|
|
1766
|
-
},
|
|
1767
|
-
_execSubscribe: function(e, t) {
|
|
1768
|
-
this._subscribers[e] && this._subscribers[e].forEach(function(e) {
|
|
1769
|
-
e.apply(this, t);
|
|
1770
|
-
});
|
|
1771
|
-
}
|
|
1772
|
-
};
|
|
1773
|
-
var _ = y, B = n(3), S = n.n(B), T = n(4), j = n(5), N = n.n(j);
|
|
1774
|
-
function w(e) {
|
|
1775
|
-
return (w = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(e) {
|
|
1776
|
-
return typeof e;
|
|
1777
|
-
} : function(e) {
|
|
1778
|
-
return e && "function" == typeof Symbol && e.constructor === Symbol && e !== Symbol.prototype ? "symbol" : typeof e;
|
|
1779
|
-
})(e);
|
|
1780
|
-
}
|
|
1781
|
-
function O(e, t) {
|
|
1782
|
-
var n = Object.keys(e);
|
|
1783
|
-
if (Object.getOwnPropertySymbols) {
|
|
1784
|
-
var r = Object.getOwnPropertySymbols(e);
|
|
1785
|
-
t && (r = r.filter(function(t) {
|
|
1786
|
-
return Object.getOwnPropertyDescriptor(e, t).enumerable;
|
|
1787
|
-
})), n.push.apply(n, r);
|
|
1788
|
-
}
|
|
1789
|
-
return n;
|
|
1790
|
-
}
|
|
1791
|
-
function V(e) {
|
|
1792
|
-
for (var t = 1; t < arguments.length; t++) {
|
|
1793
|
-
var n = null != arguments[t] ? arguments[t] : {};
|
|
1794
|
-
t % 2 ? O(Object(n), !0).forEach(function(t) {
|
|
1795
|
-
A(e, t, n[t]);
|
|
1796
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(n)) : O(Object(n)).forEach(function(t) {
|
|
1797
|
-
Object.defineProperty(e, t, Object.getOwnPropertyDescriptor(n, t));
|
|
1798
|
-
});
|
|
1799
|
-
}
|
|
1800
|
-
return e;
|
|
1801
|
-
}
|
|
1802
|
-
function A(e, t, n) {
|
|
1803
|
-
return (t = (function(e) {
|
|
1804
|
-
var t = (function(e, t) {
|
|
1805
|
-
if ("object" != w(e) || !e) return e;
|
|
1806
|
-
var n = e[Symbol.toPrimitive];
|
|
1807
|
-
if (void 0 !== n) {
|
|
1808
|
-
var r = n.call(e, t || "default");
|
|
1809
|
-
if ("object" != w(r)) return r;
|
|
1810
|
-
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
1811
|
-
}
|
|
1812
|
-
return ("string" === t ? String : Number)(e);
|
|
1813
|
-
})(e, "string");
|
|
1814
|
-
return "symbol" == w(t) ? t : t + "";
|
|
1815
|
-
})(t)) in e ? Object.defineProperty(e, t, {
|
|
1816
|
-
value: n,
|
|
1817
|
-
enumerable: !0,
|
|
1818
|
-
configurable: !0,
|
|
1819
|
-
writable: !0
|
|
1820
|
-
}) : e[t] = n, e;
|
|
1821
|
-
}
|
|
1822
|
-
function D(e, t) {
|
|
1823
|
-
var n = "undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"];
|
|
1824
|
-
if (!n) {
|
|
1825
|
-
if (Array.isArray(e) || (n = P(e)) || t && e && "number" == typeof e.length) {
|
|
1826
|
-
n && (e = n);
|
|
1827
|
-
var r = 0, o = function() {};
|
|
1828
|
-
return {
|
|
1829
|
-
s: o,
|
|
1830
|
-
n: function() {
|
|
1831
|
-
return r >= e.length ? { done: !0 } : {
|
|
1832
|
-
done: !1,
|
|
1833
|
-
value: e[r++]
|
|
1834
|
-
};
|
|
1835
|
-
},
|
|
1836
|
-
e: function(e) {
|
|
1837
|
-
throw e;
|
|
1838
|
-
},
|
|
1839
|
-
f: o
|
|
1840
|
-
};
|
|
1841
|
-
}
|
|
1842
|
-
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1843
|
-
}
|
|
1844
|
-
var i, a = !0, u = !1;
|
|
1845
|
-
return {
|
|
1846
|
-
s: function() {
|
|
1847
|
-
n = n.call(e);
|
|
1848
|
-
},
|
|
1849
|
-
n: function() {
|
|
1850
|
-
var e = n.next();
|
|
1851
|
-
return a = e.done, e;
|
|
1852
|
-
},
|
|
1853
|
-
e: function(e) {
|
|
1854
|
-
u = !0, i = e;
|
|
1855
|
-
},
|
|
1856
|
-
f: function() {
|
|
1857
|
-
try {
|
|
1858
|
-
a || null == n.return || n.return();
|
|
1859
|
-
} finally {
|
|
1860
|
-
if (u) throw i;
|
|
1861
|
-
}
|
|
1862
|
-
}
|
|
1863
|
-
};
|
|
1864
|
-
}
|
|
1865
|
-
function k(e, t) {
|
|
1866
|
-
return (function(e) {
|
|
1867
|
-
if (Array.isArray(e)) return e;
|
|
1868
|
-
})(e) || (function(e, t) {
|
|
1869
|
-
var n = null == e ? null : "undefined" != typeof Symbol && e[Symbol.iterator] || e["@@iterator"];
|
|
1870
|
-
if (null != n) {
|
|
1871
|
-
var r, o, i, a, u = [], p = !0, l = !1;
|
|
1872
|
-
try {
|
|
1873
|
-
if (i = (n = n.call(e)).next, 0 === t) {
|
|
1874
|
-
if (Object(n) !== n) return;
|
|
1875
|
-
p = !1;
|
|
1876
|
-
} else for (; !(p = (r = i.call(n)).done) && (u.push(r.value), u.length !== t); p = !0);
|
|
1877
|
-
} catch (e) {
|
|
1878
|
-
l = !0, o = e;
|
|
1879
|
-
} finally {
|
|
1880
|
-
try {
|
|
1881
|
-
if (!p && null != n.return && (a = n.return(), Object(a) !== a)) return;
|
|
1882
|
-
} finally {
|
|
1883
|
-
if (l) throw o;
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
return u;
|
|
1887
|
-
}
|
|
1888
|
-
})(e, t) || P(e, t) || (function() {
|
|
1889
|
-
throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1890
|
-
})();
|
|
1891
|
-
}
|
|
1892
|
-
function P(e, t) {
|
|
1893
|
-
if (e) {
|
|
1894
|
-
if ("string" == typeof e) return C(e, t);
|
|
1895
|
-
var n = {}.toString.call(e).slice(8, -1);
|
|
1896
|
-
return "Object" === n && e.constructor && (n = e.constructor.name), "Map" === n || "Set" === n ? Array.from(e) : "Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n) ? C(e, t) : void 0;
|
|
1897
|
-
}
|
|
1898
|
-
}
|
|
1899
|
-
function C(e, t) {
|
|
1900
|
-
(null == t || t > e.length) && (t = e.length);
|
|
1901
|
-
for (var n = 0, r = Array(t); n < t; n++) r[n] = e[n];
|
|
1902
|
-
return r;
|
|
1903
|
-
}
|
|
1904
|
-
function E() {
|
|
1905
|
-
for (var e = /(?:[0]{1,2}[:-]){5}[0]{1,2}/, t = o.a.networkInterfaces(), n = 0, r = Object.entries(t); n < r.length; n++) {
|
|
1906
|
-
var i = k(r[n], 2), a = (i[0], i[1]);
|
|
1907
|
-
if (a) {
|
|
1908
|
-
var u, p = D(a);
|
|
1909
|
-
try {
|
|
1910
|
-
for (p.s(); !(u = p.n()).done;) {
|
|
1911
|
-
var l = u.value;
|
|
1912
|
-
if (!1 === e.test(l.mac)) return l.mac;
|
|
1913
|
-
}
|
|
1914
|
-
} catch (e) {
|
|
1915
|
-
p.e(e);
|
|
1916
|
-
} finally {
|
|
1917
|
-
p.f();
|
|
1918
|
-
}
|
|
1919
|
-
}
|
|
1920
|
-
}
|
|
1921
|
-
return "00:00:00:00:00:00";
|
|
1922
|
-
}
|
|
1923
|
-
var x, M, q = (x = process.version, {
|
|
1924
|
-
os: o.a.type(),
|
|
1925
|
-
os_version: o.a.release(),
|
|
1926
|
-
app_name: "node",
|
|
1927
|
-
app_version: x,
|
|
1928
|
-
device_id: N.a.createHash("md5").update(E()).digest("hex"),
|
|
1929
|
-
platform: "node"
|
|
1930
|
-
}), I = Object(T.promisify)(S.a.resolve);
|
|
1931
|
-
function H(e) {
|
|
1932
|
-
this._offlineQueue = [], e.endpoint = e.endpoint || "gm.mmstat.com", _.call(this, V(V({}, q), e)), this._config.endpoint_url = "https://".concat(this._config.endpoint).concat("/aes.1.1");
|
|
1933
|
-
}
|
|
1934
|
-
H.prototype = ((M = function() {}).prototype = _.prototype, new M()), H.prototype.constructor = H, H.prototype.send = function(e) {
|
|
1935
|
-
var t, n = this;
|
|
1936
|
-
return (t = this._config.endpoint, I(t)).then(function(t) {
|
|
1937
|
-
return n._offlineQueue.forEach(function(e) {
|
|
1938
|
-
n.send(e);
|
|
1939
|
-
}), n._offlineQueue = [], n._print("send", e), a()(n._config.endpoint_url, {
|
|
1940
|
-
method: "POST",
|
|
1941
|
-
keepalive: true,
|
|
1942
|
-
body: JSON.stringify({
|
|
1943
|
-
gokey: encodeURIComponent(e),
|
|
1944
|
-
gmkey: "EXP"
|
|
1945
|
-
})
|
|
1946
|
-
}).catch(function() {});
|
|
1947
|
-
}).catch(function(t) {
|
|
1948
|
-
n._offlineQueue.length > 500 && n._offlineQueue.shift(), n._offlineQueue.push(e);
|
|
1949
|
-
});
|
|
1950
|
-
};
|
|
1951
|
-
t.default = H;
|
|
1952
|
-
}
|
|
1953
|
-
]).default;
|
|
1954
|
-
}));
|
|
1955
|
-
//#endregion
|
|
1956
|
-
//#region lib/remote-telemetry/event-plugin.js
|
|
1957
|
-
var require_event_plugin = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1958
|
-
module.exports = (function(e) {
|
|
1959
|
-
var t = {};
|
|
1960
|
-
function n(r) {
|
|
1961
|
-
if (t[r]) return t[r].exports;
|
|
1962
|
-
var o = t[r] = {
|
|
1963
|
-
i: r,
|
|
1964
|
-
l: !1,
|
|
1965
|
-
exports: {}
|
|
1966
|
-
};
|
|
1967
|
-
return e[r].call(o.exports, o, o.exports, n), o.l = !0, o.exports;
|
|
1968
|
-
}
|
|
1969
|
-
return n.m = e, n.c = t, n.d = function(e, t, r) {
|
|
1970
|
-
n.o(e, t) || Object.defineProperty(e, t, {
|
|
1971
|
-
enumerable: !0,
|
|
1972
|
-
get: r
|
|
1973
|
-
});
|
|
1974
|
-
}, n.r = function(e) {
|
|
1975
|
-
"undefined" != typeof Symbol && Symbol.toStringTag && Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }), Object.defineProperty(e, "__esModule", { value: !0 });
|
|
1976
|
-
}, n.t = function(e, t) {
|
|
1977
|
-
if (1 & t && (e = n(e)), 8 & t) return e;
|
|
1978
|
-
if (4 & t && "object" == typeof e && e && e.__esModule) return e;
|
|
1979
|
-
var r = Object.create(null);
|
|
1980
|
-
if (n.r(r), Object.defineProperty(r, "default", {
|
|
1981
|
-
enumerable: !0,
|
|
1982
|
-
value: e
|
|
1983
|
-
}), 2 & t && "string" != typeof e) for (var o in e) n.d(r, o, function(t) {
|
|
1984
|
-
return e[t];
|
|
1985
|
-
}.bind(null, o));
|
|
1986
|
-
return r;
|
|
1987
|
-
}, n.n = function(e) {
|
|
1988
|
-
var t = e && e.__esModule ? function() {
|
|
1989
|
-
return e.default;
|
|
1990
|
-
} : function() {
|
|
1991
|
-
return e;
|
|
1992
|
-
};
|
|
1993
|
-
return n.d(t, "a", t), t;
|
|
1994
|
-
}, n.o = function(e, t) {
|
|
1995
|
-
return Object.prototype.hasOwnProperty.call(e, t);
|
|
1996
|
-
}, n.p = "", n(n.s = 0);
|
|
1997
|
-
})([function(e, t, n) {
|
|
1998
|
-
"use strict";
|
|
1999
|
-
n.r(t);
|
|
2000
|
-
var r = [
|
|
2001
|
-
"ec",
|
|
2002
|
-
"ea",
|
|
2003
|
-
"el",
|
|
2004
|
-
"et"
|
|
2005
|
-
];
|
|
2006
|
-
var o = function(e, t) {
|
|
2007
|
-
var n = function(e) {
|
|
2008
|
-
var n = e.ec, r = e.ea, o = e.el, l = e.et, u = void 0 === l ? "CLK" : l, a = e.xpath;
|
|
2009
|
-
delete e.ec, delete e.ea, delete e.el, delete e.et, delete e.xpath, e.p1 = n, e.p2 = r, e.p3 = o, e.p4 = u, e.p5 = a;
|
|
2010
|
-
try {
|
|
2011
|
-
t.log("event", e);
|
|
2012
|
-
} catch (e) {}
|
|
2013
|
-
};
|
|
2014
|
-
return function() {
|
|
2015
|
-
var t = arguments, o = {};
|
|
2016
|
-
if (0 !== t.length) {
|
|
2017
|
-
for (var l = 0; l < t.length; l++) {
|
|
2018
|
-
var u, a, i = t[l];
|
|
2019
|
-
if (0 !== l && "object" == typeof i && l !== t.length - 1) return void (null == e || null === (u = e.console) || void 0 === u || null === (a = u.warn) || void 0 === a || a.call(u, "Only the last argument can be object type"));
|
|
2020
|
-
if ("string" == typeof i || "number" == typeof i) o[r[l]] = i;
|
|
2021
|
-
else if ("object" == typeof i && l === t.length - 1) for (var c in i) i.hasOwnProperty(c) && (o[c] = i[c]);
|
|
2022
|
-
}
|
|
2023
|
-
n(o);
|
|
2024
|
-
} else {
|
|
2025
|
-
var f, p;
|
|
2026
|
-
null === (f = e.console) || void 0 === f || null === (p = f.warn) || void 0 === p || p.call(f, "At lease one augument");
|
|
2027
|
-
}
|
|
2028
|
-
};
|
|
2029
|
-
};
|
|
2030
|
-
t.default = function(e, t) {
|
|
2031
|
-
return o(global, e);
|
|
2032
|
-
};
|
|
2033
|
-
}]).default;
|
|
2034
|
-
}));
|
|
2035
|
-
//#endregion
|
|
2036
|
-
//#region src/telemetry/sink.ts
|
|
2037
|
-
var import_tracker = /* @__PURE__ */ __toESM(require_tracker(), 1);
|
|
2038
|
-
var import_event_plugin = /* @__PURE__ */ __toESM(require_event_plugin(), 1);
|
|
2039
|
-
const TELEMETRY_FILE = () => join(getConfigDir(), "telemetry.jsonl");
|
|
2040
|
-
const MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
2041
|
-
let remoteSendEvent;
|
|
2042
|
-
const inflightSends = /* @__PURE__ */ new Set();
|
|
2043
|
-
let remoteClient = void 0;
|
|
2044
|
-
try {
|
|
2045
|
-
const client = new import_tracker.default({
|
|
2046
|
-
pid: "bailian-cli-node",
|
|
2047
|
-
env: detectEnv()
|
|
2048
|
-
});
|
|
2049
|
-
const originalSend = client.send.bind(client);
|
|
2050
|
-
client.send = function(payload) {
|
|
2051
|
-
const result = originalSend(payload);
|
|
2052
|
-
if (result && typeof result.then === "function") {
|
|
2053
|
-
const p = result;
|
|
2054
|
-
inflightSends.add(p);
|
|
2055
|
-
p.finally(() => inflightSends.delete(p));
|
|
2056
|
-
}
|
|
2057
|
-
return result;
|
|
2058
|
-
};
|
|
2059
|
-
remoteClient = client;
|
|
2060
|
-
remoteSendEvent = client.use(import_event_plugin.default);
|
|
2061
|
-
} catch {}
|
|
2062
|
-
/**
|
|
2063
|
-
* 尽力等待所有在途的埋点发送完成(best-effort)。
|
|
2064
|
-
*
|
|
2065
|
-
* 1. 先调用 `_sendAll` 排空 tracker 内部的去抖队列,把还卡在 500ms 合并窗口里
|
|
2066
|
-
* 的事件立刻推上网络。
|
|
2067
|
-
* 2. 然后用硬超时 race 所有已追踪的 fetch promise。
|
|
2068
|
-
*
|
|
2069
|
-
* 埋点永远不应阻塞 CLI:调用方应传入较短的超时(例如 1000ms),并始终与超时
|
|
2070
|
-
* race。错误与超时一律静默吞掉。
|
|
2071
|
-
*/
|
|
2072
|
-
async function flushTelemetry(timeoutMs = 1e3) {
|
|
2073
|
-
try {
|
|
2074
|
-
if (remoteClient) try {
|
|
2075
|
-
if (typeof remoteClient._sendAll === "function") remoteClient._sendAll();
|
|
2076
|
-
} catch {}
|
|
2077
|
-
if (inflightSends.size === 0) return;
|
|
2078
|
-
const pending = [...inflightSends].map((p) => p.catch(() => void 0));
|
|
2079
|
-
await Promise.race([Promise.allSettled(pending), new Promise((resolve) => setTimeout(resolve, timeoutMs).unref?.())]);
|
|
2080
|
-
} catch {}
|
|
2081
|
-
}
|
|
2082
|
-
async function localSink(event) {
|
|
2083
|
-
try {
|
|
2084
|
-
await ensureConfigDir();
|
|
2085
|
-
const path = TELEMETRY_FILE();
|
|
2086
|
-
try {
|
|
2087
|
-
if (statSync(path).size > MAX_FILE_SIZE) unlinkSync(path);
|
|
2088
|
-
} catch {}
|
|
2089
|
-
appendFileSync(path, JSON.stringify(event) + "\n", { mode: 384 });
|
|
2090
|
-
} catch {}
|
|
2091
|
-
}
|
|
2092
|
-
async function remoteSink(event) {
|
|
2093
|
-
try {
|
|
2094
|
-
if (!remoteSendEvent) return;
|
|
2095
|
-
remoteSendEvent(event.command, buildRemoteAemOptions(event));
|
|
2096
|
-
} catch {}
|
|
2097
|
-
}
|
|
2098
|
-
//#endregion
|
|
2099
|
-
//#region src/telemetry/tracker.ts
|
|
2100
|
-
const GLOBAL_FLAG_KEYS = new Set([
|
|
2101
|
-
"apiKey",
|
|
2102
|
-
"baseUrl",
|
|
2103
|
-
"output",
|
|
2104
|
-
"quiet",
|
|
2105
|
-
"verbose",
|
|
2106
|
-
"timeout",
|
|
2107
|
-
"noColor",
|
|
2108
|
-
"yes",
|
|
2109
|
-
"dryRun",
|
|
2110
|
-
"help",
|
|
2111
|
-
"nonInteractive",
|
|
2112
|
-
"async",
|
|
2113
|
-
"console"
|
|
2114
|
-
]);
|
|
2115
|
-
/**
|
|
2116
|
-
* Allowlist of flag names safe to send to telemetry.
|
|
2117
|
-
*
|
|
2118
|
-
* Default is to NOT report. Only flags whose value space is enumerable / numeric / boolean
|
|
2119
|
-
* (and therefore cannot leak user content, credentials, file paths, URLs, or customer IDs)
|
|
2120
|
-
* belong here. When adding a new flag, ask: could this field carry PII, secrets, prompts,
|
|
2121
|
-
* file paths, URLs, or tenant identifiers? If yes, do NOT add it.
|
|
2122
|
-
*/
|
|
2123
|
-
const PARAM_ALLOWLIST = new Set([
|
|
2124
|
-
"page",
|
|
2125
|
-
"pageSize",
|
|
2126
|
-
"n",
|
|
2127
|
-
"count",
|
|
2128
|
-
"model",
|
|
2129
|
-
"voice",
|
|
2130
|
-
"language",
|
|
2131
|
-
"provider",
|
|
2132
|
-
"capability",
|
|
2133
|
-
"temperature",
|
|
2134
|
-
"topP",
|
|
2135
|
-
"topK",
|
|
2136
|
-
"maxTokens",
|
|
2137
|
-
"seed",
|
|
2138
|
-
"stream",
|
|
2139
|
-
"size",
|
|
2140
|
-
"resolution",
|
|
2141
|
-
"ratio",
|
|
2142
|
-
"duration",
|
|
2143
|
-
"format",
|
|
2144
|
-
"audioFormat",
|
|
2145
|
-
"sampleRate",
|
|
2146
|
-
"pitch",
|
|
2147
|
-
"rate",
|
|
2148
|
-
"volume",
|
|
2149
|
-
"api",
|
|
2150
|
-
"mode",
|
|
2151
|
-
"download",
|
|
2152
|
-
"noWait",
|
|
2153
|
-
"textOnly",
|
|
2154
|
-
"promptExtend",
|
|
2155
|
-
"enableSsml",
|
|
2156
|
-
"watermark",
|
|
2157
|
-
"hasThoughts",
|
|
2158
|
-
"listTools",
|
|
2159
|
-
"rerank",
|
|
2160
|
-
"rerankTopN",
|
|
2161
|
-
"diarization"
|
|
2162
|
-
]);
|
|
2163
|
-
function extractParams(flags) {
|
|
2164
|
-
const params = {};
|
|
2165
|
-
for (const [key, value] of Object.entries(flags)) {
|
|
2166
|
-
if (key.startsWith("_")) continue;
|
|
2167
|
-
if (GLOBAL_FLAG_KEYS.has(key)) continue;
|
|
2168
|
-
if (!PARAM_ALLOWLIST.has(key)) continue;
|
|
2169
|
-
if (value === void 0 || value === false) continue;
|
|
2170
|
-
params[key] = value;
|
|
2171
|
-
}
|
|
2172
|
-
return params;
|
|
2173
|
-
}
|
|
2174
|
-
async function trackCommandExecution(config, commandPath, flags, fn) {
|
|
2175
|
-
if (!config.telemetry) {
|
|
2176
|
-
await fn();
|
|
2177
|
-
return;
|
|
2178
|
-
}
|
|
2179
|
-
const start = performance.now();
|
|
2180
|
-
let success = true;
|
|
2181
|
-
let errorMessage;
|
|
2182
|
-
let httpStatus;
|
|
2183
|
-
let requestId;
|
|
2184
|
-
try {
|
|
2185
|
-
await fn();
|
|
2186
|
-
} catch (err) {
|
|
2187
|
-
success = false;
|
|
2188
|
-
if (err instanceof BailianError) {
|
|
2189
|
-
errorMessage = err.message;
|
|
2190
|
-
httpStatus = err.api?.httpStatus;
|
|
2191
|
-
requestId = err.api?.requestId;
|
|
2192
|
-
} else if (err instanceof Error) errorMessage = err.message;
|
|
2193
|
-
throw err;
|
|
2194
|
-
} finally {
|
|
2195
|
-
const durationMs = Math.round(performance.now() - start);
|
|
2196
|
-
let authMethod;
|
|
2197
|
-
if (config.apiKey) authMethod = "api-key";
|
|
2198
|
-
else if (config.fileApiKey) authMethod = "api-key";
|
|
2199
|
-
else if (config.accessTokenEnv || config.fileAccessToken) authMethod = "access-token";
|
|
2200
|
-
const event = createTrackingEvent({
|
|
2201
|
-
command: commandPath.join(" "),
|
|
2202
|
-
durationMs,
|
|
2203
|
-
success,
|
|
2204
|
-
error: success ? void 0 : {
|
|
2205
|
-
message: errorMessage,
|
|
2206
|
-
httpStatus,
|
|
2207
|
-
requestId
|
|
2208
|
-
},
|
|
2209
|
-
cliVersion: config.clientVersion ?? "unknown",
|
|
2210
|
-
authMethod,
|
|
2211
|
-
params: extractParams(flags)
|
|
2212
|
-
});
|
|
2213
|
-
localSink(event).catch(() => {});
|
|
2214
|
-
remoteSink(event).catch(() => {});
|
|
2215
|
-
}
|
|
2216
|
-
}
|
|
2217
|
-
//#endregion
|
|
2218
|
-
//#region src/advisor/sources/api.ts
|
|
2219
|
-
const PAGE_SIZE = 50;
|
|
2220
|
-
function toModelProfile(item) {
|
|
2221
|
-
if (!item.model) return null;
|
|
2222
|
-
const meta = item.inferenceMetadata;
|
|
2223
|
-
return {
|
|
2224
|
-
model: item.model,
|
|
2225
|
-
name: item.name ?? item.model,
|
|
2226
|
-
description: item.description ?? item.shortDescription ?? "",
|
|
2227
|
-
shortDescription: item.shortDescription,
|
|
2228
|
-
provider: item.provider ?? "",
|
|
2229
|
-
capabilities: item.capabilities ?? [],
|
|
2230
|
-
features: item.features ?? [],
|
|
2231
|
-
category: item.category,
|
|
2232
|
-
contextWindow: item.contextWindow ?? void 0,
|
|
2233
|
-
maxOutputTokens: item.maxOutputTokens ?? void 0,
|
|
2234
|
-
maxInputTokens: item.maxInputTokens ?? void 0,
|
|
2235
|
-
docUrl: item.docUrl,
|
|
2236
|
-
collectionTag: item.collectionTag,
|
|
2237
|
-
inferenceMetadata: meta,
|
|
2238
|
-
prices: item.prices,
|
|
2239
|
-
qpmInfo: item.qpmInfo,
|
|
2240
|
-
versionTag: item.versionTag,
|
|
2241
|
-
openSource: item.openSource
|
|
2242
|
-
};
|
|
2243
|
-
}
|
|
2244
|
-
var ApiSource = class {
|
|
2245
|
-
name = "api";
|
|
2246
|
-
constructor(config) {
|
|
2247
|
-
this.config = config;
|
|
2248
|
-
}
|
|
2249
|
-
available() {
|
|
2250
|
-
return true;
|
|
2251
|
-
}
|
|
2252
|
-
async load() {
|
|
2253
|
-
const first = await fetchModelList(this.config, "", {
|
|
2254
|
-
pageNo: 1,
|
|
2255
|
-
pageSize: PAGE_SIZE
|
|
2256
|
-
});
|
|
2257
|
-
const allRaw = [...first.models];
|
|
2258
|
-
const totalPages = Math.ceil(first.total / PAGE_SIZE);
|
|
2259
|
-
for (let page = 2; page <= totalPages; page++) {
|
|
2260
|
-
const result = await fetchModelList(this.config, "", {
|
|
2261
|
-
pageNo: page,
|
|
2262
|
-
pageSize: PAGE_SIZE
|
|
2263
|
-
});
|
|
2264
|
-
allRaw.push(...result.models);
|
|
2265
|
-
}
|
|
2266
|
-
return allRaw.map(toModelProfile).filter((profile) => profile !== null);
|
|
2267
|
-
}
|
|
2268
|
-
};
|
|
2269
|
-
//#endregion
|
|
2270
|
-
//#region src/advisor/sources/catalog.ts
|
|
2271
|
-
const SKILL_DIR_NAME = "skills/doc-llm-wiki";
|
|
2272
|
-
const MODELS_FILE = "models.jsonl";
|
|
2273
|
-
function getCatalogDir() {
|
|
2274
|
-
return join$1(getConfigDir(), SKILL_DIR_NAME);
|
|
2275
|
-
}
|
|
2276
|
-
function getCatalogPath() {
|
|
2277
|
-
return join$1(getCatalogDir(), MODELS_FILE);
|
|
2278
|
-
}
|
|
2279
|
-
function getMonorepoModelsDir() {
|
|
2280
|
-
return join$1(dirname(fileURLToPath(import.meta.url)), "../../../../../skills/doc-llm-wiki/models");
|
|
2281
|
-
}
|
|
2282
|
-
function fromJsonlRecord(raw) {
|
|
2283
|
-
if (!raw.model || typeof raw.model !== "string") return null;
|
|
2284
|
-
return {
|
|
2285
|
-
model: raw.model,
|
|
2286
|
-
name: raw.name ?? raw.model,
|
|
2287
|
-
description: raw.description ?? "",
|
|
2288
|
-
provider: raw.provider ?? "",
|
|
2289
|
-
capabilities: raw.capabilities ?? [],
|
|
2290
|
-
features: raw.features ?? [],
|
|
2291
|
-
contextWindow: raw.contextWindow,
|
|
2292
|
-
maxOutputTokens: raw.maxOutputTokens,
|
|
2293
|
-
docUrl: raw.docUrl,
|
|
2294
|
-
inferenceMetadata: raw.inferenceMetadata,
|
|
2295
|
-
shortDescription: raw.shortDescription,
|
|
2296
|
-
category: raw.category,
|
|
2297
|
-
collectionTag: raw.collectionTag,
|
|
2298
|
-
maxInputTokens: raw.maxInputTokens,
|
|
2299
|
-
prices: raw.prices,
|
|
2300
|
-
qpmInfo: raw.qpmInfo,
|
|
2301
|
-
versionTag: raw.versionTag,
|
|
2302
|
-
openSource: raw.openSource,
|
|
2303
|
-
family: raw.family,
|
|
2304
|
-
familyName: raw.familyName
|
|
2305
|
-
};
|
|
2306
|
-
}
|
|
2307
|
-
function readJsonlModels(filePath) {
|
|
2308
|
-
const lines = readFileSync$1(filePath, "utf-8").split("\n").filter(Boolean);
|
|
2309
|
-
const models = [];
|
|
2310
|
-
for (const line of lines) try {
|
|
2311
|
-
const record = fromJsonlRecord(JSON.parse(line));
|
|
2312
|
-
if (record) models.push(record);
|
|
2313
|
-
} catch {}
|
|
2314
|
-
return models;
|
|
2315
|
-
}
|
|
2316
|
-
function installFromMonorepo() {
|
|
2317
|
-
const src = getMonorepoModelsDir();
|
|
2318
|
-
if (!existsSync$1(join$1(src, MODELS_FILE))) return false;
|
|
2319
|
-
const dest = getCatalogDir();
|
|
2320
|
-
try {
|
|
2321
|
-
mkdirSync$1(dest, { recursive: true });
|
|
2322
|
-
cpSync(src, dest, { recursive: true });
|
|
2323
|
-
return true;
|
|
2324
|
-
} catch {
|
|
2325
|
-
return false;
|
|
2326
|
-
}
|
|
2327
|
-
}
|
|
2328
|
-
var CatalogSource = class {
|
|
2329
|
-
name = "catalog";
|
|
2330
|
-
options;
|
|
2331
|
-
constructor(options) {
|
|
2332
|
-
this.options = options ?? {};
|
|
2333
|
-
}
|
|
2334
|
-
available() {
|
|
2335
|
-
return existsSync$1(getCatalogPath());
|
|
2336
|
-
}
|
|
2337
|
-
async load() {
|
|
2338
|
-
if (!this.available()) {
|
|
2339
|
-
this.options.onPrepareStart?.();
|
|
2340
|
-
if (!installFromMonorepo()) return [];
|
|
2341
|
-
}
|
|
2342
|
-
return readJsonlModels(getCatalogPath());
|
|
2343
|
-
}
|
|
2344
|
-
};
|
|
2345
|
-
//#endregion
|
|
2346
|
-
//#region src/advisor/cache.ts
|
|
2347
|
-
async function getModels(config, options) {
|
|
2348
|
-
const sources = [new CatalogSource({ onPrepareStart: options?.onPrepareStart }), new ApiSource(config)];
|
|
2349
|
-
for (const source of sources) if (source.available()) {
|
|
2350
|
-
const models = await source.load();
|
|
2351
|
-
if (models.length > 0) return models;
|
|
2352
|
-
}
|
|
2353
|
-
const models = await sources[0].load();
|
|
2354
|
-
if (models.length > 0) return models;
|
|
2355
|
-
throw new BailianError("No model data available.", ExitCode.GENERAL);
|
|
2356
|
-
}
|
|
2357
|
-
//#endregion
|
|
2358
|
-
//#region src/advisor/types.ts
|
|
2359
|
-
const Modalities = {
|
|
2360
|
-
Text: "Text",
|
|
2361
|
-
Image: "Image",
|
|
2362
|
-
Video: "Video",
|
|
2363
|
-
Audio: "Audio"
|
|
2364
|
-
};
|
|
2365
|
-
const Complexities = {
|
|
2366
|
-
Single: "single",
|
|
2367
|
-
Pipeline: "pipeline"
|
|
2368
|
-
};
|
|
2369
|
-
const Budgets = {
|
|
2370
|
-
Low: "low",
|
|
2371
|
-
Medium: "medium",
|
|
2372
|
-
High: "high"
|
|
2373
|
-
};
|
|
2374
|
-
const ContextNeeds = {
|
|
2375
|
-
Standard: "standard",
|
|
2376
|
-
Large: "large",
|
|
2377
|
-
ExtraLarge: "extra-large"
|
|
2378
|
-
};
|
|
2379
|
-
const QualityPreferences = {
|
|
2380
|
-
Flagship: "flagship",
|
|
2381
|
-
Balanced: "balanced",
|
|
2382
|
-
CostOptimized: "cost-optimized"
|
|
2383
|
-
};
|
|
2384
|
-
const Capabilities = {
|
|
2385
|
-
TG: "TG",
|
|
2386
|
-
Reasoning: "Reasoning",
|
|
2387
|
-
VU: "VU",
|
|
2388
|
-
IG: "IG",
|
|
2389
|
-
VG: "VG",
|
|
2390
|
-
TTS: "TTS",
|
|
2391
|
-
ASR: "ASR",
|
|
2392
|
-
RealtimeASR: "Realtime-ASR",
|
|
2393
|
-
RealtimeTTS: "Realtime-Text-to-Speech",
|
|
2394
|
-
RealtimeAudioTranslate: "Realtime-Audio-Translate",
|
|
2395
|
-
RealtimeOmni: "Realtime-Omni",
|
|
2396
|
-
MultimodalOmni: "Multimodal-Omni",
|
|
2397
|
-
ME: "ME",
|
|
2398
|
-
TR: "TR",
|
|
2399
|
-
ThreeDGeneration: "3D-generation"
|
|
2400
|
-
};
|
|
2401
|
-
const Features = {
|
|
2402
|
-
FunctionCalling: "function-calling",
|
|
2403
|
-
WebSearch: "web-search",
|
|
2404
|
-
StructuredOutputs: "structured-outputs",
|
|
2405
|
-
PrefixCompletion: "prefix-completion"
|
|
2406
|
-
};
|
|
2407
|
-
const ModelCategories = {
|
|
2408
|
-
Flagship: "Flagship",
|
|
2409
|
-
CostOptimized: "Cost-optimized"
|
|
2410
|
-
};
|
|
2411
|
-
//#endregion
|
|
2412
|
-
//#region src/advisor/constants/prompts.ts
|
|
2413
|
-
const INTENT_MODEL = "qwen-flash";
|
|
2414
|
-
const RANKING_MODEL = "qwen3.6-flash";
|
|
2415
|
-
const RANKING_MODEL_FAST = "qwen-flash";
|
|
2416
|
-
const INTENT_SYSTEM_PROMPT = `You are an intent analyzer. Given the user's requirement, understand the scenario first, then extract structured information.
|
|
2417
|
-
|
|
2418
|
-
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. All text fields (taskSummary, scenarioHints) must be in English.
|
|
2419
|
-
|
|
2420
|
-
## Analysis Steps
|
|
2421
|
-
1. Summarize the user's core need in one sentence (taskSummary) — be specific about the scenario, not generic
|
|
2422
|
-
2. Infer scenario hints (scenarioHints), e.g.: ["low-latency", "consumer-facing", "high-concurrency", "conversational", "offline-batch", "high-precision"]
|
|
2423
|
-
3. Infer budget and qualityPreference from scenario hints
|
|
2424
|
-
- Only deviate from defaults when the user explicitly states or the scenario strongly implies
|
|
2425
|
-
- User says "low cost", "cheap", "save money" → budget:"low"
|
|
2426
|
-
- User says "best", "high precision", "cost no object" → qualityPreference:"flagship"
|
|
2427
|
-
- Infer from scenario constraints only when strong: e.g. "1M requests/day customer service" → budget:"low" (high concurrency = cost-sensitive)
|
|
2428
|
-
- Otherwise keep budget:"medium", qualityPreference:"balanced"
|
|
2429
|
-
4. Extract modalities, capabilities, features etc.
|
|
2430
|
-
|
|
2431
|
-
## Model preference detection
|
|
2432
|
-
Analyze whether the user mentioned specific models, model families, or vendors:
|
|
2433
|
-
- No models/families/vendors mentioned → mode:"unconstrained", no targets
|
|
2434
|
-
- User scoped the range (e.g. "recommend from the deepseek family", "open-source reasoning models") → mode:"scoped", targets:["deepseek"]
|
|
2435
|
-
- User wants to compare specific models (e.g. "compare wan2.6 and wan2.7", "is qwen-max good for legal analysis") → mode:"comparison", targets:["wan2.6","wan2.7"]
|
|
2436
|
-
- Single model evaluation is also comparison with one target
|
|
2437
|
-
- User wants alternatives to a reference model (e.g. "something like qwen-max but cheaper") → mode:"alternative", targets:["qwen-max"]
|
|
2438
|
-
- User explicitly excludes certain models/families (e.g. "good models besides qwen") → excludes:["qwen"], mode determined by other signals
|
|
2439
|
-
- targets should capture the model/family names as the user wrote them
|
|
2440
|
-
|
|
2441
|
-
## Output fields
|
|
2442
|
-
- taskSummary: one-sentence scenario understanding (must be specific, never generic like "user wants AI")
|
|
2443
|
-
- scenarioHints: array of inferred scenario features
|
|
2444
|
-
- complexity: "single" or "pipeline"
|
|
2445
|
-
- segments: only for pipeline, each with step/inputModality/outputModality/requiredCapabilities
|
|
2446
|
-
- step must describe the specific problem this step solves in the user's task, no numbered or generic modal labels
|
|
2447
|
-
- segments must form a modality chain: each step's inputModality should cover the previous step's outputModality
|
|
2448
|
-
- inputModality: user input modalities ["Text","Image","Video","Audio"]
|
|
2449
|
-
- outputModality: expected output modalities
|
|
2450
|
-
- requiredCapabilities: capability codes (use strictly from the list, don't invent):
|
|
2451
|
-
TG=Text Generation, Reasoning=Reasoning, VU=Vision Understanding, IG=Image Generation, VG=Video Generation,
|
|
2452
|
-
TTS=Text-to-Speech, ASR=Speech-to-Text, Realtime-ASR=Realtime Speech-to-Text,
|
|
2453
|
-
Realtime-Text-to-Speech=Realtime Text-to-Speech, Realtime-Audio-Translate=Realtime Audio Translation,
|
|
2454
|
-
Realtime-Omni=Realtime Omni-modal, Multimodal-Omni=Multimodal Omni, ME=Multimodal Embedding,
|
|
2455
|
-
TR=Translation, 3D-generation=3D Generation
|
|
2456
|
-
- requiredFeatures: required features (function-calling, web-search, structured-outputs, prefix-completion)
|
|
2457
|
-
- budget: "low"/"medium"/"high"
|
|
2458
|
-
- contextNeed: "standard"/"large"/"extra-large"
|
|
2459
|
-
- qualityPreference: "flagship"/"balanced"/"cost-optimized"
|
|
2460
|
-
- modelPreference: { mode, targets?, excludes? }
|
|
2461
|
-
|
|
2462
|
-
Output only JSON, no other text.`;
|
|
2463
|
-
const SINGLE_SYSTEM_PROMPT = `You are a model recommendation advisor for Alibaba Cloud Model Studio. From the candidate models below, select the best recommendations.
|
|
1
|
+
import{createRequire as e}from"node:module";import{appendFileSync as t,createReadStream as n,existsSync as r,mkdirSync as i,readFileSync as a,renameSync as o,statSync as s,unlinkSync as c,writeFileSync as l}from"fs";import{homedir as u}from"os";import{basename as d,extname as f,join as p}from"path";import{stringify as m}from"yaml";import{createHash as h,createHmac as g,randomUUID as _}from"crypto";import{Readable as v}from"stream";import{createInterface as y}from"readline";import{cpSync as ee,existsSync as b,mkdirSync as x,readFileSync as S,readdirSync as C,writeFileSync as te}from"node:fs";import{dirname as w,join as T}from"node:path";import{fileURLToPath as ne}from"node:url";var re=Object.create,ie=Object.defineProperty,ae=Object.getOwnPropertyDescriptor,E=Object.getOwnPropertyNames,D=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty,O=(e,t)=>()=>(t||(e((t={exports:{}}).exports,t),e=null),t.exports),k=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=E(t),a=0,o=i.length,s;a<o;a++)s=i[a],!oe.call(e,s)&&s!==n&&ie(e,s,{get:(e=>t[e]).bind(null,s),enumerable:!(r=ae(t,s))||r.enumerable});return e},A=(e,t,n)=>(n=e==null?{}:re(D(e)),k(t||!e||!e.__esModule?ie(n,`default`,{value:e,enumerable:!0}):n,e)),j=e(import.meta.url);const M={SUCCESS:0,GENERAL:1,USAGE:2,AUTH:3,QUOTA:4,TIMEOUT:5,NETWORK:6,CONTENT_FILTER:10};var N=class extends Error{exitCode;hint;api;constructor(e,t=M.GENERAL,n,r){super(e,r?.cause===void 0?void 0:{cause:r.cause}),this.name=`BailianError`,this.exitCode=t,this.hint=n,this.api=r?.api}toJSON(){let e=se(this.cause);return{error:{code:this.exitCode,message:this.message,...this.hint?{hint:this.hint}:{},...this.api?.httpStatus===void 0?{}:{http_status:this.api.httpStatus},...this.api?.apiCode?{api_code:this.api.apiCode}:{},...this.api?.requestId?{request_id:this.api.requestId}:{},...e?{cause:e}:{}}}}};function se(e){if(e!=null){if(e instanceof Error){let t={message:e.message},n=e.code;return n&&(t.code=n),t}if(typeof e==`string`||typeof e==`number`||typeof e==`boolean`)return{message:String(e)};try{return{message:JSON.stringify(e)}}catch{return}}}function P(e,t,n){let r=t.error?.message||t.message||`HTTP ${e}`,i=t.error?.type??t.code,a=typeof i==`string`?i:typeof i==`number`?String(i):void 0;return new N(r,M.GENERAL,void 0,{api:{httpStatus:e,apiCode:a,requestId:t.request_id}})}const F={cn:`https://dashscope.aliyuncs.com`,us:`https://dashscope-us.aliyuncs.com`,intl:`https://dashscope-intl.aliyuncs.com`},ce={cn:`https://help.aliyun.com/zh/model-studio`,us:`https://help.aliyun.com/zh/model-studio`,intl:`https://help.aliyun.com/zh/model-studio`},le=`https://bailian.cn-beijing.aliyuncs.com`,ue=new Set([`text`,`json`]),de=new Set([`domestic`,`international`]);function fe(e){try{let t=new URL(e);return t.protocol===`http:`||t.protocol===`https:`}catch{return!1}}function pe(e){if(!e||typeof e!=`object`||Array.isArray(e))return{};let t=e,n={};return typeof t.api_key==`string`&&(n.api_key=t.api_key),typeof t.access_token==`string`&&t.access_token.length>0?n.access_token=t.access_token:typeof t.accessToken==`string`&&t.accessToken.length>0&&(n.access_token=t.accessToken),typeof t.base_url==`string`&&fe(t.base_url)&&(n.base_url=t.base_url),typeof t.output==`string`&&ue.has(t.output)&&(n.output=t.output),typeof t.output_dir==`string`&&t.output_dir.length>0&&(n.output_dir=t.output_dir),typeof t.timeout==`number`&&t.timeout>0&&(n.timeout=t.timeout),typeof t.default_text_model==`string`&&t.default_text_model.length>0&&(n.default_text_model=t.default_text_model),typeof t.default_video_model==`string`&&t.default_video_model.length>0&&(n.default_video_model=t.default_video_model),typeof t.default_image_model==`string`&&t.default_image_model.length>0&&(n.default_image_model=t.default_image_model),typeof t.default_speech_model==`string`&&t.default_speech_model.length>0&&(n.default_speech_model=t.default_speech_model),typeof t.default_omni_model==`string`&&t.default_omni_model.length>0&&(n.default_omni_model=t.default_omni_model),typeof t.access_key_id==`string`&&t.access_key_id.length>0&&(n.access_key_id=t.access_key_id),typeof t.access_key_secret==`string`&&t.access_key_secret.length>0&&(n.access_key_secret=t.access_key_secret),typeof t.workspace_id==`string`&&t.workspace_id.length>0&&(n.workspace_id=t.workspace_id),typeof t.console_site==`string`&&de.has(t.console_site)&&(n.console_site=t.console_site),typeof t.console_region==`string`&&t.console_region.length>0&&(n.console_region=t.console_region),typeof t.console_switch_agent==`number`&&t.console_switch_agent>0&&(n.console_switch_agent=t.console_switch_agent),typeof t.telemetry==`boolean`&&(n.telemetry=t.telemetry),n}function I(){return process.env.BAILIAN_CONFIG_DIR?process.env.BAILIAN_CONFIG_DIR:p(u(),`.bailian`)}function L(){return p(I(),`config.json`)}function me(){return p(I(),`credentials.json`)}async function R(){let e=I(),t=await import(`fs/promises`);await t.mkdir(e,{recursive:!0,mode:448});try{await t.chmod(e,448)}catch{}}function he(e){return m(e).replace(/\n$/,``)}function ge(e){return JSON.stringify(e,null,2)}function _e(e,t,n){return JSON.stringify({error:{code:e,message:t,...n?{hint:n}:{}}},null,2)}function ve(e){return e===`json`||e===`text`?e:process.stdout.isTTY?`text`:`json`}function ye(e,t){switch(t){case`json`:return ge(e);case`text`:return he(e)}}function be(){let e=L();if(!r(e))return{};try{return pe(JSON.parse(a(e,`utf-8`)))}catch(e){let t=e;return(t instanceof SyntaxError||t.message.includes(`JSON`))&&console.warn(`Warning: config file is corrupted; using defaults.`),{}}}async function xe(e){await R();let t=L(),n=t+`.tmp`;l(n,JSON.stringify(e,null,2)+`
|
|
2
|
+
`,{mode:384}),o(n,t)}function Se(e){let t=be(),n=e.apiKey||void 0,r=t.api_key,i=process.env.DASHSCOPE_ACCESS_TOKEN?.trim()||void 0,a=t.access_token?.trim()||void 0,o=e.baseUrl||t.base_url||process.env.DASHSCOPE_BASE_URL||F.cn,s=ve(e.output||process.env.DASHSCOPE_OUTPUT||t.output),c=process.env.DASHSCOPE_TIMEOUT?Number(process.env.DASHSCOPE_TIMEOUT):void 0,l=c!==void 0&&Number.isFinite(c)&&c>0?c:void 0,u=e.timeout??l??t.timeout??300;if(!Number.isFinite(u)||u<=0)throw new N(`Timeout must be a positive finite number.`,M.USAGE);return{apiKey:n,accessTokenEnv:i,fileAccessToken:a,fileApiKey:r,configPath:L(),baseUrl:o,output:s,outputDir:t.output_dir||void 0,timeout:u,defaultTextModel:t.default_text_model,defaultVideoModel:t.default_video_model,defaultImageModel:t.default_image_model,defaultSpeechModel:t.default_speech_model,defaultOmniModel:t.default_omni_model,accessKeyId:process.env.ALIBABA_CLOUD_ACCESS_KEY_ID||t.access_key_id||void 0,accessKeySecret:process.env.ALIBABA_CLOUD_ACCESS_KEY_SECRET||t.access_key_secret||void 0,workspaceId:process.env.BAILIAN_WORKSPACE_ID||t.workspace_id||void 0,consoleSite:e.consoleSite||t.console_site||void 0,consoleRegion:e.consoleRegion||t.console_region||void 0,consoleSwitchAgent:e.consoleSwitchAgent||t.console_switch_agent||void 0,verbose:e.verbose||process.env.DASHSCOPE_VERBOSE===`1`,quiet:e.quiet||!1,noColor:e.noColor||process.env.NO_COLOR!==void 0||!process.stdout.isTTY,yes:e.yes||!1,dryRun:e.dryRun||!1,nonInteractive:e.nonInteractive||!1,async:e.async||!1,telemetry:process.env.DO_NOT_TRACK===`1`?!1:t.telemetry??!0}}function Ce(){let e=L();if(!r(e))return null;try{let t=a(e,`utf-8`),n=JSON.parse(t);return typeof n.api_key==`string`&&n.api_key.length>0?n.api_key:null}catch{return null}}async function we(e){await R();let t=L(),n={};try{n=JSON.parse(a(t,`utf-8`))}catch{}n.api_key=e;let r=t+`.tmp`;l(r,JSON.stringify(n,null,2)+`
|
|
3
|
+
`,{mode:384}),o(r,t)}async function Te(){let e=L();if(r(e))try{let t=JSON.parse(a(e,`utf-8`));delete t.api_key,delete t.access_token;let n=e+`.tmp`;l(n,JSON.stringify(t,null,2)+`
|
|
4
|
+
`,{mode:384}),o(n,e)}catch{}}async function Ee(e){if(e.apiKey)return{token:e.apiKey,method:`api-key`,source:`flag`};if(e.fileApiKey)return{token:e.fileApiKey,method:`api-key`,source:`config.json`};if(e.accessTokenEnv)return{token:e.accessTokenEnv,method:`access-token`,source:`DASHSCOPE_ACCESS_TOKEN`};if(e.fileAccessToken)return{token:e.fileAccessToken,method:`access-token`,source:`config.json`};if(process.env.DASHSCOPE_API_KEY)return{token:process.env.DASHSCOPE_API_KEY,method:`api-key`,source:`DASHSCOPE_API_KEY`};throw new N(`No credentials found.`,M.AUTH,`Set DASHSCOPE_API_KEY environment variable, pass --api-key, or configure a key.`)}const De=`No console access token found.`;async function Oe(e){if(e.accessTokenEnv)return{token:e.accessTokenEnv,method:`access-token`,source:`DASHSCOPE_ACCESS_TOKEN`};if(e.fileAccessToken)return{token:e.fileAccessToken,method:`access-token`,source:`config.json`};throw new N(De,M.AUTH,"Run `bl auth login --console` or set DASHSCOPE_ACCESS_TOKEN.")}function ke(e){let t=e.method??`POST`,n=new Date().toISOString().replace(/\.\d{3}Z$/,`Z`),r=_(),i=Ae(e.body),a={host:e.host,"x-acs-action":e.action,"x-acs-version":e.version,"x-acs-date":n,"x-acs-signature-nonce":r,"x-acs-content-sha256":i,"content-type":`application/json`},o=Object.keys(a).filter(e=>e===`host`||e===`content-type`||e.startsWith(`x-acs-`)).sort(),s=o.map(e=>`${e}:${a[e]}`).join(`
|
|
5
|
+
`)+`
|
|
6
|
+
`,c=o.join(`;`),l=[t,e.pathname,``,s,c,i].join(`
|
|
7
|
+
`),u=`ACS3-HMAC-SHA256`,d=`${u}\n${Ae(l)}`,f=je(e.accessKeySecret,d);return a.authorization=`${u} Credential=${e.accessKeyId},SignedHeaders=${c},Signature=${f}`,a}function Ae(e){return h(`sha256`).update(e,`utf8`).digest(`hex`)}function je(e,t){return g(`sha256`,e).update(t,`utf8`).digest(`hex`)}function Me(e){return`${e}/compatible-mode/v1/chat/completions`}function Ne(e){return`${e}/api/v1/services/aigc/image-generation/generation`}function Pe(e){return`${e}/api/v1/services/aigc/multimodal-generation/generation`}function Fe(e){return`${e}/api/v1/services/aigc/video-generation/video-synthesis`}function Ie(e,t){return`${e}/api/v1/tasks/${encodeURIComponent(t)}`}function Le(e,t){return`${e}/api/v1/apps/${encodeURIComponent(t)}/completion`}function Re(e){return`${e}/api/v2/apps/memory/add`}function ze(e){return`${e}/api/v2/apps/memory/memory_nodes/search`}function Be(e){return`${e}/api/v2/apps/memory/memory_nodes`}function Ve(e,t){return`${e}/api/v2/apps/memory/memory_nodes/${encodeURIComponent(t)}`}function He(e){return`${e}/api/v1/services/audio/tts/SpeechSynthesizer`}function Ue(e){return`${e}/api/v1/services/audio/asr/transcription`}function We(e){return`${e}/api/v2/apps/memory/profile_schemas`}function Ge(e,t){return`${e}/api/v2/apps/memory/profile_schemas/${encodeURIComponent(t)}/profiles`}function Ke(e){return`${e}/api/v1/indices/rag/index/retrieve`}function qe(e){return`https://${e}.cn-beijing.maas.aliyuncs.com/api/v1/indices/knowledge/search`}function Je(e){return`https://${e}.cn-beijing.maas.aliyuncs.com/api/v2/apps/knowledge/chat`}function Ye(e){return`${e}/api/v1/mcps/WebSearch/mcp`}function Xe(e){return`${e}/compatible-mode/v1/files`}function Ze(e){return`${e}/api/v1/files`}function Qe(e,t){return`${e}/api/v1/files/${encodeURIComponent(t)}`}function $e(e){return`${e}/api/v1/fine-tunes`}function et(e,t){return`${e}/api/v1/fine-tunes/${encodeURIComponent(t)}`}function tt(e,t){return`${e}/api/v1/fine-tunes/${encodeURIComponent(t)}/cancel`}function nt(e,t){return`${e}/api/v1/fine-tunes/${encodeURIComponent(t)}/logs`}function rt(e,t){return`${e}/api/v1/fine-tunes/${encodeURIComponent(t)}/checkpoints`}function it(e,t,n){return`${e}/api/v1/fine-tunes/${encodeURIComponent(t)}/export/${encodeURIComponent(n)}`}function at(e){return`${e}/api/v1/deployments`}function ot(e,t){return`${e}/api/v1/deployments/${encodeURIComponent(t)}`}function st(e,t){return`${e}/api/v1/deployments/${encodeURIComponent(t)}/scale`}function ct(e,t){return`${e}/api/v1/deployments/${encodeURIComponent(t)}/update`}function lt(e){return`${e}/api/v1/deployments/models`}const ut=`bailian-cli`,dt={t1:`public`,t2:``},ft=JSON.stringify({channel:ut,tags:dt});function z(){return{"x-dashscope-source-config":ft}}function pt(e){return e.length>8?`${e.slice(0,4)}...${e.slice(-4)}`:`***`}function mt(e){return typeof e!=`object`||!e||e instanceof FormData?!1:JSON.stringify(e).includes(`oss://`)}async function ht(e,t){let n=typeof FormData<`u`&&t.body instanceof FormData,r={"User-Agent":`${e.clientName??`bailian-cli-core`}/${e.clientVersion??`0.0.0-dev`}`,...z(),...t.headers};if(!n&&!r[`Content-Type`]&&(r[`Content-Type`]=`application/json`),t.async&&(r[`X-DashScope-Async`]=`enable`),mt(t.body)&&(r[`X-DashScope-OssResourceResolve`]=`enable`),!t.noAuth){let n=await Ee(e);r.Authorization=`Bearer ${n.token}`,e.verbose&&(console.error(`> ${t.method??`GET`} ${t.url}`),console.error(`> Auth: ${pt(n.token)}`),console.error(`> x-dashscope-source-config: ${ft}`))}let i=gt((t.timeout??e.timeout)*1e3,t.signal),a=await fetch(t.url,{method:t.method??`GET`,headers:r,body:t.body?n?t.body:JSON.stringify(t.body):void 0,signal:i.signal}).finally(i.cleanup);if(e.verbose){console.error(`< ${a.status} ${a.statusText}`);let e=a.headers.get(`x-request-id`);e&&console.error(`request_id: ${e}`)}if(!a.ok){let e={};try{e=await a.json()}catch{}throw P(a.status,e,t.url)}return a}function gt(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(),e),i=()=>n.abort(t?.reason),a=()=>{clearTimeout(r),t?.removeEventListener(`abort`,i)};return t?.aborted?i():t?.addEventListener(`abort`,i,{once:!0}),n.signal.addEventListener(`abort`,a,{once:!0}),{signal:n.signal,cleanup:a}}async function B(e,t){let n=await ht(e,t),r;try{r=await n.json()}catch{throw new N(`API returned non-JSON response (${n.headers.get(`content-type`)||`unknown type`}). Server may be experiencing issues.`,M.GENERAL)}if(r.code&&typeof r.code==`string`&&r.code!==`200`&&r.code!==`Success`)throw P(200,{error:{message:r.message,type:r.code}},t.url);return r}function _t(e,t){return`${e.replace(/\/$/,``)}/api/v1/mcps/${t}/mcp`}var vt=class{url;sessionId;nextId=1;config;authToken;constructor(e,t){this.config=e,this.url=t}async initialize(){let e=await Ee(this.config);this.authToken=e.token;let t=await this.rpc(`initialize`,{protocolVersion:`2025-03-26`,capabilities:{},clientInfo:{name:this.config.clientName??`bailian-cli-core`,version:this.config.clientVersion??`0.0.0-dev`}});this.config.verbose&&(console.error(`[MCP] Session initialized: ${this.sessionId??`no session`}`),console.error(`[MCP] Server: ${JSON.stringify(t)}`)),await this.notify(`notifications/initialized`)}async listTools(){return(await this.rpc(`tools/list`)).tools||[]}async callTool(e,t){return await this.rpc(`tools/call`,{name:e,arguments:t})}async rpc(e,t){let n={jsonrpc:`2.0`,id:this.nextId++,method:e,...t?{params:t}:{}},r=await(await this.send(n)).json();if(r.error)throw new N(`MCP error (${r.error.code}): ${r.error.message}`,M.GENERAL);return r.result}async notify(e,t){let n={jsonrpc:`2.0`,method:e,...t?{params:t}:{}};await this.send(n)}async send(e){let t={"Content-Type":`application/json`,Accept:`application/json, text/event-stream`,"User-Agent":`${this.config.clientName??`bailian-cli-core`}/${this.config.clientVersion??`0.0.0-dev`}`,...z()};this.authToken&&(t.Authorization=`Bearer ${this.authToken}`),this.sessionId&&(t[`Mcp-Session-Id`]=this.sessionId),this.config.verbose&&(console.error(`> POST ${this.url}`),console.error(`> Method: ${e.method}`));let n=this.config.timeout*1e3,r=await fetch(this.url,{method:`POST`,headers:t,body:JSON.stringify(e),signal:AbortSignal.timeout(n)});this.config.verbose&&console.error(`< ${r.status} ${r.statusText}`);let i=r.headers.get(`Mcp-Session-Id`)||r.headers.get(`mcp-session-id`);if(i&&(this.sessionId=i),!r.ok){let e=`MCP request failed: ${r.status} ${r.statusText}`;try{let t=await r.text();t&&(e+=` - ${t.slice(0,500)}`)}catch{}throw new N(e,M.GENERAL)}return r}};async function*yt(e){let t=e.body?.getReader();if(!t)return;let n=new TextDecoder,r=``,i=16*1024*1024;try{for(;;){let{done:e,value:a}=await t.read();if(e)break;if(r+=n.decode(a,{stream:!0}),r.length>i)throw new N(`SSE stream exceeded the maximum buffer size.`,M.GENERAL);let o=r.split(`
|
|
8
|
+
`);r=o.pop()||``;let s={};for(let e of o){if(e===``){s.data!==void 0&&(yield{data:s.data,event:s.event,id:s.id}),s={};continue}if(e.startsWith(`:`))continue;let t=e.indexOf(`:`);if(t===-1)continue;let n=e.slice(0,t),r=e.slice(t+1).trimStart();switch(n){case`data`:if(s.data=s.data===void 0?r:`${s.data}\n${r}`,s.data.length>i)throw new N(`SSE event exceeded the maximum buffer size.`,M.GENERAL);break;case`event`:s.event=r;break;case`id`:s.id=r;break}}}if(r.trim()&&r.includes(`data:`)){let e=r.indexOf(`:`);e!==-1&&(yield{data:r.slice(e+1).trimStart()})}}finally{t.releaseLock()}}const bt={"cn-beijing":{domestic:{csGateway:`bailian-cs.console.aliyun.com`,action:`BroadScopeAspnGateway`},international:{csGateway:`bailian-cs.console.alibabacloud.com`,action:`BroadScopeAspnGateway`}},"ap-southeast-1":{domestic:{csGateway:`modelstudio-cs.console.aliyun.com`,action:`IntlBroadScopeAspnGateway`},international:{csGateway:`bailian-singapore-cs.alibabacloud.com`,action:`IntlBroadScopeAspnGateway`}}};function xt(e,t){return bt[e]?.[t]??bt[`cn-beijing`][t]}function St(e){let t=e.consoleRegion??`cn-beijing`,n=e.consoleSite??`domestic`,r=e.consoleSwitchAgent;return r==null?{consoleRegion:t,consoleSite:n}:{consoleRegion:t,consoleSite:n,consoleSwitchAgent:r}}function Ct(e,t,n){return JSON.stringify({Api:e,V:`1.0`,Data:{...t,cornerstoneParam:{protocol:`V2`,console:`ONE_CONSOLE`,productCode:`p_efm`,consoleSite:`BAILIAN_ALIYUN`,...n==null?{}:{switchAgent:n},...typeof t.cornerstoneParam==`object`&&t.cornerstoneParam!==null?t.cornerstoneParam:{}}}})}async function wt(e,t,{api:n,data:r}){let{consoleRegion:i,consoleSite:a,consoleSwitchAgent:o}=St(e),s=xt(i,a),c=`https://${s.csGateway}`,l=s.action,u=Ct(n,r,o),d=new URLSearchParams({params:u,region:i}),f=e.timeout*1e3,p={Accept:`*/*`,"Content-Type":`application/x-www-form-urlencoded`};t&&(p.Authorization=`Bearer ${t}`);let m=await fetch(`${c}/cli/api.json?action=${l}&product=sfm_bailian&api=${encodeURIComponent(n)}`,{method:`POST`,headers:p,body:d.toString(),signal:AbortSignal.timeout(f)});if(!m.ok){let e=await m.text().catch(()=>``);throw new N(`Console CLI gateway failed: HTTP ${m.status} ${m.statusText}`,M.GENERAL,e.slice(0,500))}let h=await m.json(),g=h.data;if(g?.success===!1&&g.errorCode){let e=g.errorCode,t=typeof e==`string`?e:JSON.stringify(e),n=t.includes(`NotLogined`),r=typeof g.errorMsg==`string`?g.errorMsg:void 0;throw new N(n?`Console session is not logged in or has expired.`:`Console gateway error: ${t}`,n?M.AUTH:M.GENERAL,n?"Run `bl auth login --console` to sign in or refresh your console session.":r&&r!==t?r:void 0)}return h}async function Tt(e,t,n={}){let{pageNo:r=1,pageSize:i=50,name:a=``,providers:o=[],capabilities:s=[]}=n,c=await wt(e,t,{api:`zeldaHttp.dashscopeModel./zelda/api/v1/modelCenter/listFoundationModels`,data:{input:{pageNo:r,pageSize:i,name:a,providers:o,inferenceProviders:[],features:[],group:!0,capabilities:s,contextWindows:[]}}}),l=c?.data?.DataV2?.data??c?.data??{},u=l?.data?.total??l?.total??0,d=l?.data?.list??l?.list??[],f=[];for(let e of d)if(e.items?.length)for(let t of e.items)f.push(t);else f.push(e);return{total:u,models:f}}const Et=`${F.cn}/api/v1/uploads`;async function Dt(e,t,n){let r=`${Et}?action=getPolicy&model=${encodeURIComponent(t)}`,i=Mt(15e3,n),a=await fetch(r,{headers:{Authorization:`Bearer ${e}`,"Content-Type":`application/json`,...z()},signal:i.signal}).finally(i.cleanup);if(!a.ok){let e=await a.text().catch(()=>``);throw new N(`Failed to get upload policy (HTTP ${a.status}): ${e}`,M.GENERAL)}return(await a.json()).data}async function Ot(e,t,n){let r=d(t),i=`${e.upload_dir}/${r}`,o=a(t),s=new FormData;s.append(`OSSAccessKeyId`,e.oss_access_key_id),s.append(`Signature`,e.signature),s.append(`policy`,e.policy),s.append(`x-oss-object-acl`,e.x_oss_object_acl),s.append(`x-oss-forbid-overwrite`,e.x_oss_forbid_overwrite),s.append(`key`,i),s.append(`success_action_status`,`200`),s.append(`file`,new Blob([o]),r);let c=Mt(12e4,n),l=await fetch(e.upload_host,{method:`POST`,headers:{...z()},body:s,signal:c.signal}).finally(c.cleanup);if(!l.ok){let e=await l.text().catch(()=>``);throw new N(`Failed to upload file to OSS (HTTP ${l.status}): ${e}`,M.GENERAL)}return`oss://${i}`}async function kt(e){let{apiKey:t,model:n,filePath:i,signal:a}=e;if(!r(i))throw new N(`File not found: ${i}`,M.USAGE);if(!s(i).isFile())throw new N(`Not a file: ${i}`,M.USAGE);return Ot(await Dt(t,n,a),i,a)}function At(e){return e.startsWith(`http://`)||e.startsWith(`https://`)||e.startsWith(`oss://`)||e.startsWith(`data:`)?!1:r(e)}async function jt(e,t,n,r={}){return At(e)?kt({apiKey:t,model:n,filePath:e,signal:r.signal}):e}function Mt(e,t){let n=new AbortController,r=setTimeout(()=>n.abort(),e),i=()=>n.abort(t?.reason),a=()=>{clearTimeout(r),t?.removeEventListener(`abort`,i)};return t?.aborted?i():t?.addEventListener(`abort`,i,{once:!0}),n.signal.addEventListener(`abort`,a,{once:!0}),{signal:n.signal,cleanup:a}}async function Nt(e,t){let{filePath:r,purpose:i=`fine-tune`,signal:a}=t,o=s(r),c=d(r),l=v.toWeb(n(r)),u=await new Response(l).blob(),f=new FormData;f.append(`file`,u,c),f.append(`purpose`,i);let p=await B(e,{url:Xe(e.baseUrl),method:`POST`,body:f,signal:a});if(p.id)return{file_id:p.id,name:p.filename??c,size:p.bytes??o.size,purpose:p.purpose??i,gmt_create:p.created_at?new Date(p.created_at*1e3).toISOString():void 0};let m=p.data?.failed_uploads;if(Array.isArray(m)&&m.length>0){let e=m[0]??{};throw new N(`Dataset upload failed${e.code?` [${e.code}]`:``}: ${e.message??`no message returned`}`,M.GENERAL,`Server reported failure for ${c}. Re-run with --verbose to see the raw response.`)}throw new N(`Dataset upload of ${c} returned no file_id (HTTP 200 with empty payload).`,M.GENERAL,`The platform accepted the request but did not allocate a file_id. Retry the upload; if it recurs, contact platform support with the request id.`)}async function Pt(e,t={}){let n=new URLSearchParams;t.pageNo!==void 0&&n.set(`page_no`,String(t.pageNo)),t.pageSize!==void 0&&n.set(`page_size`,String(t.pageSize)),t.purpose&&n.set(`purpose`,t.purpose);let r=Ze(e.baseUrl);return B(e,{url:n.toString()?`${r}?${n.toString()}`:r,method:`GET`,signal:t.signal})}async function Ft(e,t,n){return B(e,{url:Qe(e.baseUrl,t),method:`GET`,signal:n})}async function It(e,t,n){let r=await ht(e,{url:Qe(e.baseUrl,t),method:`DELETE`,signal:n});try{return await r.json()}catch{return{data:{deleted:!0,file_id:t}}}}const Lt=300*1024*1024;function Rt(e,t=Lt){if(!r(e))throw new N(`File not found: ${e}`,M.USAGE);let n=s(e);if(!n.isFile())throw new N(`Not a regular file: ${e}`,M.USAGE);if(n.size===0)throw new N(`File is empty: ${e}`,M.USAGE);if(n.size>t)throw new N(`File too large: ${(n.size/(1024*1024)).toFixed(1)}MB exceeds the ${(t/(1024*1024)).toFixed(0)}MB dataset upload cap.`,M.USAGE);return{bytes:n.size,ext:f(e).toLowerCase()}}function V(e,t,n,r={}){return{severity:e,code:t,message:n,...r}}function zt(e){if(e===void 0||e.trim()===``)return;let t=e.trim();if(t===`chatml`||t===`dpo`||t===`cpt`)return t;throw new N(`Unsupported --schema "${e}". Supported: chatml, dpo, cpt.`,M.USAGE,`Omit --schema to auto-detect per record (chosen/rejected → DPO, text → CPT, else ChatML).`)}function Bt(e,t=50,n=100,r=10){if(e<=0)return[];if(e<=t+r)return Array.from({length:e},(e,t)=>t+1);let i=new Set;for(let n=1;n<=Math.min(t,e);n++)i.add(n);for(let t=0;t<r;t++)i.add(e-t);let a=Math.max(1,Math.ceil(e/n));for(let n=t+1;n<=e-r;n+=a)i.add(n);return[...i].filter(t=>t>=1&&t<=e).sort((e,t)=>e-t)}const Vt=new Set([`system`,`user`,`assistant`]);function Ht(e,t,n){let r=[];if(typeof e!=`object`||!e||Array.isArray(e))return r.push(V(`error`,`MESSAGE_NOT_OBJECT`,`Message must be an object.`,{line:t,path:n})),r;let i=e,a=i.role,o=i.content;return(typeof a!=`string`||!Vt.has(a))&&r.push(V(`error`,`INVALID_ROLE`,`Invalid role "${String(a)}". Expected one of: system, user, assistant.`,{line:t,path:`${n}.role`})),typeof o!=`string`&&r.push(V(`error`,`INVALID_CONTENT`,`"content" must be a string (got ${typeof o}).`,{line:t,path:`${n}.content`})),r}function Ut(e,t){let n=[],r=e.messages;if(!Array.isArray(r))return n.push(V(`error`,`MISSING_MESSAGES`,`Required field "messages" is missing or not an array.`,{line:t,path:`messages`})),n;if(r.length===0)return n.push(V(`error`,`EMPTY_MESSAGES`,`"messages" must contain at least one entry.`,{line:t,path:`messages`})),n;let i=!1,a;for(let e=0;e<r.length;e++){let o=r[e],s=`messages[${e}]`;n.push(...Ht(o,t,s));let c=o?.role;c===`system`&&(e!==0&&n.push(V(`warning`,`SYSTEM_NOT_FIRST`,`"system" message should appear at index 0; found at index ${e}.`,{line:t,path:`${s}.role`})),i=!0),a===c&&(c===`user`||c===`assistant`)&&n.push(V(`warning`,`ROLE_NOT_ALTERNATING`,`Consecutive ${c} messages — user/assistant turns should typically alternate.`,{line:t,path:`${s}.role`})),typeof c==`string`&&(a=c)}return r.some(e=>e.role===`user`)||n.push(V(`warning`,`NO_USER_ROLE`,`No "user" message found in this sample.`,{line:t,path:`messages`})),i&&r.length===1&&n.push(V(`warning`,`SYSTEM_ONLY`,`Sample only contains a "system" message.`,{line:t,path:`messages`})),n}const Wt={name:`chatml`,detect:()=>!0,inspect:Ut};function Gt(e,t){let n=[];if(!(`text`in e))return n.push(V(`error`,`MISSING_TEXT`,`Required field "text" is missing.`,{line:t,path:`text`})),n;let r=e.text;return typeof r==`string`?(r.trim().length===0&&n.push(V(`error`,`EMPTY_TEXT`,`"text" must not be empty / whitespace-only.`,{line:t,path:`text`})),n):(n.push(V(`error`,`INVALID_TEXT`,`"text" must be a string (got ${typeof r}).`,{line:t,path:`text`})),n)}const Kt={name:`cpt`,detect:e=>`text`in e&&!(`messages`in e),inspect:Gt};function qt(e,t){let n=Ut(e,t),r=e.messages;if(!Array.isArray(r)||r.length===0)return n;let i=`chosen`in e,a=`rejected`in e;if(i||n.push(V(`error`,`MISSING_CHOSEN`,`DPO record is missing the "chosen" preference.`,{line:t,path:`chosen`})),a||n.push(V(`error`,`MISSING_REJECTED`,`DPO record is missing the "rejected" preference.`,{line:t,path:`rejected`})),i){n.push(...Ht(e.chosen,t,`chosen`));let r=e.chosen?.role;typeof r==`string`&&r!==`assistant`&&n.push(V(`warning`,`PREFERENCE_ROLE_NOT_ASSISTANT`,`"chosen" role should be "assistant" (got "${r}").`,{line:t,path:`chosen.role`}))}if(a){n.push(...Ht(e.rejected,t,`rejected`));let r=e.rejected?.role;typeof r==`string`&&r!==`assistant`&&n.push(V(`warning`,`PREFERENCE_ROLE_NOT_ASSISTANT`,`"rejected" role should be "assistant" (got "${r}").`,{line:t,path:`rejected.role`}))}return n}const Jt=[{name:`dpo`,detect:e=>`chosen`in e||`rejected`in e,inspect:qt},Kt,Wt];function Yt(e,t){return t===void 0?Jt.find(t=>t.detect(e))??Wt:Jt.find(e=>e.name===t)||Wt}async function Xt(e,t){let r=y({input:n(e,{encoding:`utf8`}),crlfDelay:1/0}),i=[],a=0,o=0;for await(let e of r){if(t?.aborted)break;a++;let n=e.trim();if(n.length===0){o++;continue}i.length>=20||(n[0]!==`{`||n[n.length-1]!==`}`)&&i.push(V(`error`,`MALFORMED_LINE`,`Line does not start with '{' and end with '}'. JSONL requires one minified JSON object per line — pretty-printed JSON or arrays are not accepted here.`,{line:a}))}return{totalLines:a,blankLines:o,issues:i}}async function Zt(e,t,r,i,a){let o=r?null:new Set(Bt(t)),s=[],c=0,l=y({input:n(e,{encoding:`utf8`}),crlfDelay:1/0}),u=0;for await(let e of l){if(a?.aborted)break;if(u++,o&&!o.has(u))continue;let t=e.trim();if(t.length===0||(c++,s.length>=30))continue;let n;try{n=JSON.parse(t)}catch(e){s.push(V(`error`,`MALFORMED_JSON`,`JSON.parse failed: ${e.message}`,{line:u}));continue}s.push(...Qt(n,u,i))}return{sampled:c,issues:s}}function Qt(e,t,n){if(typeof e!=`object`||!e||Array.isArray(e))return[V(`error`,`RECORD_NOT_OBJECT`,`Each line must be a JSON object, got ${Array.isArray(e)?`array`:typeof e}.`,{line:t})];let r=e;return Yt(r,n).inspect(r,t)}const H=[{format:`jsonl`,extensions:[`.jsonl`],async validate(e,t){let n=Date.now(),r=await Xt(e,t.signal);if(r.totalLines===0||r.totalLines===r.blankLines)return{valid:!1,format:`jsonl`,filePath:e,errors:[V(`error`,`EMPTY_FILE`,`File contains no non-blank lines.`)],warnings:[],stats:{totalRecords:0,sampledRecords:0,durationMs:Date.now()-n}};if(r.issues.length>0)return{valid:!1,format:`jsonl`,filePath:e,errors:r.issues,warnings:[],stats:{totalRecords:r.totalLines-r.blankLines,sampledRecords:0,durationMs:Date.now()-n}};let i=await Zt(e,r.totalLines,!!t.fullValidate,t.schema,t.signal),a=i.issues.filter(e=>e.severity===`error`),o=i.issues.filter(e=>e.severity===`warning`);return{valid:a.length===0,format:`jsonl`,filePath:e,errors:a,warnings:o,stats:{totalRecords:r.totalLines-r.blankLines,sampledRecords:i.sampled,durationMs:Date.now()-n}}}}];function $t(e){let t=f(e).toLowerCase(),n=H.find(e=>e.extensions.includes(t));if(!n){let e=H.flatMap(e=>e.extensions).join(`, `);throw new N(`Unsupported dataset format "${t||`(none)`}". Supported: ${e}`,M.USAGE,`Convert your data to one of the supported formats and re-run.`)}return n}function en(e){H.some(t=>t.format===e.format)||H.push(e)}async function tn(e,t={}){let{bytes:n}=Rt(e,t.maxBytes??314572800),r=await $t(e).validate(e,t);return r.stats.bytes===void 0&&(r.stats.bytes=n),r}function nn(){return H.map(e=>({format:e.format,extensions:[...e.extensions]}))}function rn(e){let t=[];e.line!==void 0&&t.push(`line ${e.line}`),e.path&&t.push(e.path);let n=t.length?` [${t.join(` · `)}]`:``;return` ${e.severity.toUpperCase()} ${e.code}${n}: ${e.message}`}async function an(e,t,n){return B(e,{url:$e(e.baseUrl),method:`POST`,body:t,signal:n})}async function on(e,t={}){let n=new URLSearchParams;t.pageNo!==void 0&&n.set(`page_no`,String(t.pageNo)),t.pageSize!==void 0&&n.set(`page_size`,String(t.pageSize)),t.status&&n.set(`status`,t.status);let r=$e(e.baseUrl);return B(e,{url:n.toString()?`${r}?${n.toString()}`:r,method:`GET`,signal:t.signal})}async function sn(e,t,n){return B(e,{url:et(e.baseUrl,t),method:`GET`,signal:n})}async function cn(e,t,n){return B(e,{url:tt(e.baseUrl,t),method:`POST`,signal:n})}async function ln(e,t,n){return B(e,{url:et(e.baseUrl,t),method:`DELETE`,signal:n})}async function un(e,t,n={}){let r=new URLSearchParams;n.pageNo!==void 0&&r.set(`page_no`,String(n.pageNo)),n.pageSize!==void 0&&r.set(`page_size`,String(n.pageSize));let i=nt(e.baseUrl,t);return B(e,{url:r.toString()?`${i}?${r.toString()}`:i,method:`GET`,signal:n.signal})}async function dn(e,t,n){return B(e,{url:rt(e.baseUrl,t),method:`GET`,signal:n})}async function fn(e,t,n,r,i){let a=new URLSearchParams;return a.set(`model_name`,r),B(e,{url:`${it(e.baseUrl,t,n)}?${a.toString()}`,method:`GET`,signal:i})}const U={sft:{server:`sft`,method:`sft`,variant:`full`},"sft-lora":{server:`efficient_sft`,method:`sft`,variant:`lora`},dpo:{server:`dpo_full`,method:`dpo`,variant:`full`},"dpo-lora":{server:`dpo_lora`,method:`dpo`,variant:`lora`},cpt:{server:`cpt`,method:`cpt`,variant:`full`}},pn=Object.keys(U),mn=`sft-lora`;function hn(e){return e in U}function gn(e){return U[e].server}function _n(e){let{method:t,variant:n}=U[e];return{method:t,variant:n}}function vn(e,t){if(!e)return!1;let{method:n,variant:r}=U[t];if(e.supports?.[n]!==!0)return!1;let i=e.trainingTypes?.[n];return Array.isArray(i)&&i.includes(r)}function yn(e){return e?pn.filter(t=>vn(e,t)):[]}async function bn(e,t){return(await Tt(e,``,{name:t,pageSize:20})).models.find(e=>e.model===t)??null}const xn=`INSUFFICIENT_SAMPLES`;function Sn(e){let{recordCount:t,batchSize:n}=e;return t>n?{ok:!0}:{ok:!1,issue:{severity:`error`,code:xn,message:`Training dataset has ${t} sample(s), which is not greater than batch_size (${n}).`},hint:[`The platform requires the number of training samples to exceed batch_size.`,`Options:`,` • add more data (recommended: comfortably more than batch_size, since the`,` platform also holds back a default 0.9 train split),`,` • lower --batch-size (server clamps to a minimum of 8).`].join(`
|
|
9
|
+
`)}}async function Cn(e,t,n){return B(e,{url:at(e.baseUrl),method:`POST`,body:t,signal:n})}async function wn(e,t={}){let n=new URLSearchParams;t.pageNo!==void 0&&n.set(`page_no`,String(t.pageNo)),t.pageSize!==void 0&&n.set(`page_size`,String(t.pageSize)),t.status&&n.set(`status`,t.status);let r=at(e.baseUrl);return B(e,{url:n.toString()?`${r}?${n.toString()}`:r,method:`GET`,signal:t.signal})}async function Tn(e,t,n){return B(e,{url:ot(e.baseUrl,t),method:`GET`,signal:n})}async function En(e,t,n){return B(e,{url:ot(e.baseUrl,t),method:`DELETE`,signal:n})}async function Dn(e,t={}){let n=new URLSearchParams;t.pageNo!==void 0&&n.set(`page_no`,String(t.pageNo)),t.pageSize!==void 0&&n.set(`page_size`,String(t.pageSize)),t.version&&n.set(`version`,t.version),t.modelSource&&n.set(`model_source`,t.modelSource);let r=lt(e.baseUrl);return B(e,{url:n.toString()?`${r}?${n.toString()}`:r,method:`GET`,signal:t.signal})}async function On(e,t,n,r){return B(e,{url:st(e.baseUrl,t),method:`PUT`,body:n,signal:r})}async function kn(e,t,n,r){return B(e,{url:ct(e.baseUrl,t),method:`PUT`,body:n,signal:r})}function An(e){return{description:e.description,usageArgs:e.usageArgs,options:e.options,exampleArgs:e.exampleArgs,skipDefaultApiKeySetup:e.skipDefaultApiKeySetup,notes:e.notes,execute:(t,n)=>e.run(t,n)}}const jn=[{flag:`--api-key <key>`,description:`API key`},{flag:`--base-url <url>`,description:`API base URL`},{flag:`--output <format>`,description:`Output format: text, json`},{flag:`--timeout <seconds>`,description:`Request timeout`,type:`number`},{flag:`--quiet`,description:`Suppress non-essential output`},{flag:`--verbose`,description:`Print HTTP request/response details`},{flag:`--no-color`,description:`Disable ANSI colors`},{flag:`--dry-run`,description:`Dry run mode`},{flag:`--non-interactive`,description:`Disable interactive prompts`},{flag:`--concurrent <n>`,description:`Run N parallel requests (default: 1)`,type:`number`},{flag:`--console-region <region>`,description:`Console gateway region (e.g. cn-beijing, ap-southeast-1)`},{flag:`--console-site <site>`,description:`Console site: domestic, international`},{flag:`--console-switch-agent <uid>`,description:`Switch agent UID for delegated access`,type:`number`},{flag:`--help`,description:`Show help`},{flag:`--version`,description:`Print version`}];function Mn(e,t){return e.normalize(`NFKC`).replace(/[\\/:*?"<>|]/g,`_`).replace(/\s+/g,`_`).replace(/_+/g,`_`).replace(/^_+|_+$/g,``)||t}function Nn(e,t){return`${Mn(e||`image`,`image`)}_${Mn((t||``).substring(0,20),`untitled`)}_${Date.now()}`}const Pn=()=>p(u(),`bailian-output`);function Fn(e,t){let n=t?.flagDir||e.outputDir||Pn(),a=t?.subDir?p(n,t.subDir):n;return r(a)||i(a,{recursive:!0}),a}function In(e){return e?.nonInteractive===!0||process.env.CI?!1:process.stdout.isTTY===!0&&process.stdin.isTTY===!0}function Ln(){return!!(process.env.CI||process.env.GITHUB_ACTIONS||process.env.GITLAB_CI||process.env.JENKINS_URL||process.env.TRAVIS||process.env.CIRCLECI)}function Rn(e){for(let t of Object.keys(e))e[t]===void 0&&delete e[t];return e}function zn(e,t=`boolean`){if(typeof e==`boolean`)return e;if(typeof e==`string`){let t=e.trim().toLowerCase();if(t===`true`)return!0;if(t===`false`)return!1}throw new N(`Invalid ${t} value "${String(e)}". Use true or false.`,M.USAGE)}function Bn(e,t=`boolean`){if(e!=null)return zn(e,t)}function Vn(e,t,n=`boolean`){let r=Bn(e,n);return r===void 0?t:r}function Hn(e){return Bn(e,`watermark`)??!0}function Un(e){let t={command:e.command,timestamp:new Date().toISOString(),durationMs:e.durationMs,success:e.success,cliVersion:e.cliVersion,nodeVersion:process.version,os:process.platform};return e.authMethod&&(t.authMethod=e.authMethod),!e.success&&e.error&&(e.error.message&&(t.errorMessage=e.error.message),e.error.httpStatus!==void 0&&(t.httpStatus=e.error.httpStatus),e.error.requestId&&(t.requestId=e.error.requestId)),e.params&&Object.keys(e.params).length>0&&(t.params=e.params),t}function Wn(e){if(e==null)return;let t=typeof e==`string`?e:JSON.stringify(e);return t.length<=500?t:t.slice(0,500)}function Gn(e){let{command:t,params:n,...r}=e,i={et:`EXP`,ext:r,c1:n,c2:e.success?`success`:`failure`};return e.httpStatus!==void 0&&(i.c3=String(e.httpStatus)),e.errorMessage&&(i.c4=Wn(e.errorMessage)),e.requestId&&(i.c5=e.requestId),i}let W;function Kn(){return W||(process.env.NODE_ENV===`development`?(W=`dev`,W):(W=import.meta.url.includes(`/node_modules/`)?`prod`:`dev`,W))}var qn=O(((e,t)=>{t.exports=(function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){typeof Symbol<`u`&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:`Module`}),Object.defineProperty(e,`__esModule`,{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t||4&t&&typeof e==`object`&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,`default`,{enumerable:!0,value:e}),2&t&&typeof e!=`string`)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,`a`,t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p=``,n(n.s=8)})([function(e,t){e.exports=j(`os`)},function(e,t){e.exports=globalThis.fetch},function(e,t,n){e.exports=n(6)},function(e,t){e.exports=j(`dns`)},function(e,t){e.exports=j(`util`)},function(e,t){e.exports=j(`crypto`)},function(e,t,n){Object.defineProperty(t,Symbol.toStringTag,{value:`Module`});let r=n(7),i=(e,t)=>{t.appName=`BaiduSpider`,t.appVersion=e.value,t.deviceBrand=`Baidu`,t.deviceType=`bot`,t.platform=`other`},a=(e,t)=>{t.appName=`360 Spider`,t.appVersion=e.value,t.deviceBrand=`360`,t.deviceType=`bot`,t.platform=`other`},o=(e,t)=>{t.appName=`BingBot`,t.appVersion=e.value,t.deviceBrand=`Microsoft`,t.deviceType=`bot`,t.platform=`other`},s=(e,t)=>{t.appName=`Googlebot`,t.appVersion=e.value,t.deviceBrand=`Google`,t.deviceType=`bot`,t.platform=`other`},c=(e,t)=>{t.appName=`YandexBot`,t.appVersion=e.value,t.deviceBrand=`Yandex`,t.deviceType=`bot`,t.platform=`other`},l=(e,t)=>{e.getPreviousNTokens(3)===`Sogou web spider`&&(t.deviceBrand=`Sogou.com`,t.appName=`SogouSpider`),t.appVersion=e.value,t.deviceType=`bot`},u=(e,t)=>{t.appName=`DataproviderBot`,t.appVersion=e.value,t.deviceBrand=`Dataprovider.com`,t.deviceType=`bot`,t.platform=`other`},d=(e,t)=>{t.appName=`AhrefsBot`,t.appVersion=e.value,t.deviceBrand=`Ahrefs`,t.deviceType=`bot`,t.platform=`other`},f=(e,t)=>{t.appName=`BitSightBot`,t.appVersion=e.value,t.deviceBrand=`Bitsight`,t.deviceType=`bot`,t.platform=`other`},p=(e,t)=>{t.appName=`oBot`,t.appVersion=e.value,t.deviceBrand=`IBM`,t.deviceType=`bot`,t.platform=`other`},m=(e,t)=>{t.appName=`Cincraw`,t.appVersion=e.value,t.deviceBrand=`CINC`,t.deviceType=`bot`,t.platform=`other`},h=(e,t)=>{t.appName=`DingTalkBot`,t.appVersion=e.value,t.deviceBrand=`Alibaba`,t.deviceType=`bot`,t.platform=`other`},g=(e,t)=>{t.appName=`YisouSpider`,t.appVersion=e.value,t.deviceBrand=`Alibaba`,t.deviceType=`bot`,t.platform=`other`},_=(e,t)=>{t.appName=`ByteSpider`,t.appVersion=e.value,t.deviceBrand=`ByteDance`,t.deviceType=`bot`,t.platform=`other`},v=(e,t)=>{t.appName=`HeadlineCrawler`,t.appVersion=e.value,t.deviceBrand=`Headline.com`,t.deviceType=`bot`,t.platform=`other`},y=(e,t)=>{t.appName=`BitDiscoveryBot`,t.appVersion=e.value,t.deviceBrand=`Tenable`,t.deviceType=`bot`,t.platform=`other`},ee=(e,t)=>{e.getPreviousNTokens(4)===`Screaming Frog SEO Spider`&&(t.deviceBrand=`Screaming Frog`,t.appName=`Screaming Frog`),t.appVersion=e.value,t.deviceType=`bot`},b=(e,t)=>{t.appName=`Ai2Bot`,t.appVersion=e.value,t.deviceBrand=`Ai2`,t.deviceType=`bot`,t.platform=`other`},x=(e,t)=>{t.appName=`DianjingAdSpider`,t.appVersion=e.value,t.deviceBrand=`Dianjing`,t.deviceType=`bot`,t.platform=`other`},S=(e,t)=>{t.appName=`BaiduSpider`,t.appVersion=e.value,t.deviceBrand=`Baidu`,t.deviceType=`bot`,t.platform=`other`},C=(e,t)=>{t.appName=`360 Spider`,t.appVersion=e.value,t.deviceBrand=`360`,t.deviceType=`bot`,t.platform=`other`},te=(e,t)=>{t.appName=`BingBot`,t.appVersion=e.value,t.deviceBrand=`Microsoft`,t.deviceType=`bot`,t.platform=`other`},w=(e,t)=>{t.appName=`Googlebot`,t.appVersion=e.value,t.deviceBrand=`Google`,t.deviceType=`bot`,t.platform=`other`},T=(e,t)=>{t.appName=`YandexBot`,t.appVersion=e.value,t.deviceBrand=`Yandex`,t.deviceType=`bot`,t.platform=`other`},ne=(e,t)=>{e.getPreviousNTokens(3)===`Sogou web spider`&&(t.deviceBrand=`Sogou.com`,t.appName=`SogouSpider`),t.appVersion=e.value,t.deviceType=`bot`},re=(e,t)=>{t.appName=`DataproviderBot`,t.appVersion=e.value,t.deviceBrand=`Dataprovider.com`,t.deviceType=`bot`,t.platform=`other`},ie=(e,t)=>{t.appName=`AhrefsBot`,t.appVersion=e.value,t.deviceBrand=`Ahrefs`,t.deviceType=`bot`,t.platform=`other`},ae=(e,t)=>{t.appName=`BitSightBot`,t.appVersion=e.value,t.deviceBrand=`Bitsight`,t.deviceType=`bot`,t.platform=`other`},E=(e,t)=>{t.appName=`oBot`,t.appVersion=e.value,t.deviceBrand=`IBM`,t.deviceType=`bot`,t.platform=`other`},D=(e,t)=>{t.appName=`Cincraw`,t.appVersion=e.value,t.deviceBrand=`CINC`,t.deviceType=`bot`,t.platform=`other`},oe=(e,t)=>{t.appName=`DingTalkBot`,t.appVersion=e.value,t.deviceBrand=`Alibaba`,t.deviceType=`bot`,t.platform=`other`},O=(e,t)=>{t.appName=`YisouSpider`,t.appVersion=e.value,t.deviceBrand=`Alibaba`,t.deviceType=`bot`,t.platform=`other`},k=(e,t)=>{t.appName=`ByteSpider`,t.appVersion=e.value,t.deviceBrand=`ByteDance`,t.deviceType=`bot`,t.platform=`other`},A=(e,t)=>{t.appName=`HeadlineCrawler`,t.appVersion=e.value,t.deviceBrand=`Headline.com`,t.deviceType=`bot`,t.platform=`other`},j=(e,t)=>{t.appName=`BitDiscoveryBot`,t.appVersion=e.value,t.deviceBrand=`Tenable`,t.deviceType=`bot`,t.platform=`other`},M=(e,t)=>{e.getPreviousNTokens(4)===`Screaming Frog SEO Spider`&&(t.deviceBrand=`Screaming Frog`,t.appName=`Screaming Frog`),t.appVersion=e.value,t.deviceType=`bot`},N=(e,t)=>{t.appName=`Ai2Bot`,t.appVersion=e.value,t.deviceBrand=`Ai2`,t.deviceType=`bot`,t.platform=`other`},se=(e,t)=>{t.appName=`DianjingAdSpider`,t.appVersion=e.value,t.deviceBrand=`Dianjing`,t.deviceType=`bot`,t.platform=`other`},P=new Map,F=new Map;P.set(`Baiduspider-render`,i),P.set(`Baiduspider+`,i),P.set(`Baiduspider-image+`,i),P.set(`360Spider`,a),P.set(`360Spider-Image`,a),P.set(`bingbot`,o),P.set(`Googlebot`,s),P.set(`YandexRenderResourcesBot`,c),P.set(`spider`,l),P.set(`Dataprovider.com`,u),P.set(`AhrefsBot`,d),P.set(`BitSightBot`,f),P.set(`oBot`,p),P.set(`Cincraw`,m),P.set(`DingTalkBot-LinkService`,h),P.set(`YisouSpider`,g),P.set(`Bytespider`,_),P.set(`ev-crawler`,v),P.set(`bitdiscovery`,y),P.set(`Spider`,ee),P.set(`Ai2Bot-Dolma`,b),P.set(`dianjing_ad_spider`,x),F.set(`Baiduspider-render`,S),F.set(`Baiduspider+`,S),F.set(`Baiduspider-image+`,S),F.set(`360Spider`,C),F.set(`360Spider-Image`,C),F.set(`bingbot`,te),F.set(`Googlebot`,w),F.set(`YandexRenderResourcesBot`,T),F.set(`spider`,ne),F.set(`Dataprovider.com`,re),F.set(`AhrefsBot`,ie),F.set(`BitSightBot`,ae),F.set(`oBot`,E),F.set(`Cincraw`,D),F.set(`DingTalkBot-LinkService`,oe),F.set(`YisouSpider`,O),F.set(`Bytespider`,k),F.set(`ev-crawler`,A),F.set(`bitdiscovery`,j),F.set(`Spider`,M),F.set(`Ai2Bot-Dolma`,N),F.set(`dianjing_ad_spider`,se);let ce={productHandlerMap:P,commentHandlerMap:F,getSpecialProductHandler:()=>null,getSpecialCommentHandler:()=>null,getDefaultModelHandler:()=>null};t.isBot=function(e){let t=r.createUAInfo();return r.runTask(e,t,ce),t.deviceType===`bot`}},function(e,t){function n(e){let t=[],n={parent:e,tokens:t,get firstToken(){return t.length===0?null:t[0]},getNewToken(r){let i=(function(){let e=[],t=[],n=[],r=null,i=null,a=null,o=!0,s=!0,c=!0,l=null,u={get key(){return o&&=(r=e.join(``),!1),r},get value(){return s&&=(i=t.join(``),!1),i},get originValue(){return c&&=(a=n.join(``),!1),a},previousToken:null,properties:null,appendKey(t){e.push(t),o=!0},appendValue(e){t.push(e===`_`?`.`:e),n.push(e),s=!0,c=!0,l=null},getSplitValue(e){if(l===null){let e=u.value;l=e===``?[]:e.split(`/`)}return e>=0&&e<l.length?l[e]:null},getPreviousNTokens(e){let t=[],n=u;for(let r=0;r<e;r++){if(n==null)return null;t.unshift(n.key),n=n.previousToken}return t.join(` `)}};return u})();return t.push(i),i.previousToken=r===void 0?t.length>1?t[t.length-2]:null:r,e&&(e.properties=n),i},getLastToken:()=>t.length===0?null:t[t.length-1],getFirstToken:()=>t.length===0?null:t[0],isEmpty:()=>t.length===0};return n}function r(){return{appName:null,appVersion:null,browserName:null,browserVersion:null,engineName:null,engineVersion:null,deviceBrand:null,deviceModel:null,deviceType:`mobile`,osName:null,osVersion:null,platform:`web`,tokenGroup:n(null)}}let i=new Set(` ;,"'`.split(``)),a=new Set(`/=:`.split(``)),o=new Set([`Mozilla`,`AppleWebKit`,`Safari`,`Opera`,`Dalvik`,`com.ss.android.ugc.aweme`]);function s(e){return e.length===1&&i.has(e)}function c(e){return e.length===1&&a.has(e)}function l(e,t,n,r){if(e==null)return;let i=t.parent,a=e.key,s=null;if(i!=null){let e=i.key;o.has(e)?(s=r.commentHandlerMap.get(a)??null,s??=r.getSpecialCommentHandler(a),s==null&&a.endsWith(` Build`)&&(s=r.getDefaultModelHandler())):s=r.productHandlerMap.get(a)??r.getSpecialProductHandler(a)}else s=r.productHandlerMap.get(a)??r.getSpecialProductHandler(a);if(s!=null)try{s(e,n)}catch{}}function u(e,t,r){if(e==null)throw Error(`input can not be null`);return(function e(t,r,i,a,o){let u,d=null,f=null,p=!1,m=t.length,h=r>0?t[r-1]:`\0`;for(u=r;u<m;u++){let g=t[u];if(s(g)){let e=h!==`\0`&&s(h);if(!p&&r>0&&g===` `&&!e){let e=u+1;if(e<m){let n=t[e];/\d/.test(n)||n===`-`?p=!0:f?.appendKey(g)}else f?.appendKey(g)}else f!=null&&(d=f,f=null);h=g}else if(g===`(`){if(h===`(`){h=g;continue}let r=u;u=e(t,u+1,n(i.getLastToken()),a,o),f!=null&&(d=f,f=null),h=t[r]}else{if(g===`)`){if(r===0){h=g;continue}break}f??(l(i.getLastToken(),i,a,o),f=i.getNewToken(d),p=!1),c(g)?(p&&f.appendValue(g),p=!0):p?f.appendValue(g):f.appendKey(g),h=g}}return l(i.getLastToken(),i,a,o),u})(e,0,t.tokenGroup,t,r),t}Object.defineProperty(t,`DEFAULT_MODEL_HANDLER_KEY`,{enumerable:!0,get:function(){return`DEFAULT_MODEL_HANDLER`}}),Object.defineProperty(t,`createUAInfo`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(t,`runTask`,{enumerable:!0,get:function(){return u}})},function(e,t,n){n.r(t);var r=n(0),i=n.n(r),a=n(1),o=n.n(a);n(2);function s(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:20,t=arguments.length>1?arguments[1]:void 0;return t||=``,e?s(--e,`0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz`.charAt(Math.floor(60*Math.random()))+t):t}function c(e,t){for(var n in t)e[n]=t[n];return e}function l(e){return Object.prototype.toString.call(e)===`[object Object]`}function u(e){return typeof Promise<`u`&&e instanceof Promise}var d=Object.freeze({__aesBeforeSkip:1}),f=function(e){var t=Object.prototype.toString.call(e);if(t===`[object String]`&&e||t===`[object Number]`||t===`[object Boolean]`)return e;if(t===`[object Object]`||t===`[object Array]`)try{return JSON.stringify(e)}catch{}},p=function(e){var t={};for(var n in e){var r=e[n];r!==void 0&&(t[n]=f(r))}return t},m=function(e){var t=[];for(var n in e){var r=f(e[n]);r!==void 0&&t.push(`${n}=${encodeURIComponent(r)}`)}return t.join(`&`)};function h(e){return(e.requiredFields||[]).concat([`pid`]).some(function(t){return e[t]===void 0})}function g(){var e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:``,t=arguments.length>1?arguments[1]:void 0;typeof console<`u`&&console.warn(`日志解析报错,埋点将被丢弃 => ${e}`,t)}var _=`AEM_TRACKER_UNIQUE_PVID`,v=typeof globalThis<`u`&&globalThis?globalThis:typeof window<`u`&&window?window:typeof global<`u`&&global?global:typeof self<`u`&&self?self:(console.error(`Unable to locate global object in current environment`),{});function y(e){this._queue=[],this._reqQueue=[],this._plugins={},this._subscribers={onConfigUpdated:[]},this._timeout=0,this._config={sdk_version:`3.3.18`,set pv_id(e){v[_]=e},get pv_id(){return v[_]||(v[_]=s()),v[_]},timezone_offset:new Date().getTimezoneOffset()},e&&(this._config=c(this._config,e))}y.prototype={constructor:y,_sendAll:function(){if(this._timeout&&=(clearTimeout(this._timeout),0),this._queue.length){var e,t=this._config.maxUrlLength||3e4,n=this._getSendConfig();try{e=this._processData(this._queue,n)}catch{}if(e&&e.length<t)return this._queue=[],void this.send(e);for(var r,i=[];this._queue.length;){i.push(this._queue.shift());try{r=this._processData(i,n)}catch(e){var a=i.pop();g(e.message,a);continue}if(r.length>t){i.length>1&&(this._queue.unshift(i.pop()),r=this._processData(i,n));break}}r&&this.send(r),this._queue.length&&this._sendAll()}},_send:function(e,t){var n=this;if(!1===t){var r;try{r=this._processData([e])}catch(t){g(t.message,e)}r&&this.send(r)}else{this._queue.push(e);var i=this._config.mergeRequestInterval||500;this._timeout||=setTimeout(function(){n._sendAll()},i)}},_getSendConfig:function(){var e={},t=this._config;for(var n in t)n!==`requiredFields`&&n!==`maxUrlLength`&&n!==`queueGlobalName`&&n!==`debug`&&n!==`excludeCrawlers`&&n!==`collectClientHints`&&n.indexOf(`plugin`)!==0&&t[n]!==``&&t[n]!==null&&t[n]!==void 0&&(e[n]=f(t[n]));return e},_processData:function(e,t){t||=this._getSendConfig();var n=m(t);return n+=`&msg=`+encodeURIComponent(e.map(function(e){return m(e)}).join(`|`))},setConfig:function(e,t){var n=this,r={};t===void 0?r=e:r[e]=t;var i=!(function e(t,n){if(t===void 0||n===void 0||!l(t)||!l(n))return!1;for(var r in t)if(l(t[r])){if(!e(t[r],n[r]))return!1}else if(t[r]!==n[r])return!1;return!0})(r,this._config),a=function(){if(i){for(var e in r)l(r[e])?n._config[e]=c(n._config[e]||{},r[e]):n._config[e]=r[e];n._execSubscribe(`onConfigUpdated`,[r,n._config])}};this._reqQueue.length?(a(),h(this._config)||(this._reqQueue.forEach(function(e){n._send.apply(n,e)}),this._reqQueue=[])):(i&&this._sendAll(),a())},getConfig:function(e){return e?this._config[e]:this._config},updatePVID:(function(e,t){if(typeof e!=`function`)throw TypeError(`Expected a function`);t=typeof t==`number`&&t>=0?t:100;var n=null;return function(){if(n===null){var r=this,i=Array.prototype.slice.call(arguments);n=setTimeout(function(){n=null},t),e.apply(r,i)}}})(function(){v[_]=s()},200),log:function(e){var t=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:{};e&&(t.ts=t.ts||new Date().getTime(),t.type=e,this._print(`log`,e,t),t=p(t),h(this._config)?this._reqQueue.length<1e3&&this._reqQueue.push([t,n.combo]):this._send(t,n.combo))},before:function(e,t){var n=this;return function(){var r=arguments,i=t.apply(n,r);i!==d&&(u(i)?i.then(function(t){t!==d&&e.apply(n,t||r)}):e.apply(n,i||r))}},after:function(e,t){var n=this;return function(){var r=arguments;e.apply(n,r),t.apply(n,r)}},use:function(e,t){var n=this;return Object.prototype.toString.call(e)===`[object Array]`?e.map(function(e){if(Object.prototype.toString.call(e)===`[object Array]`){var t=e[0],r=e[1];return n._plugins[t]||(n._plugins[t]=new t(n,r))}return n._plugins[e]||(n._plugins[e]=new e(n))}):this._plugins[e]||(this._plugins[e]=new e(this,t))},_print:function(){this._config.debug&&typeof console<`u`&&console.log.apply(console,arguments)},onConfigUpdated:function(e){this._subscribers.onConfigUpdated&&this._subscribers.onConfigUpdated.push(e)},_execSubscribe:function(e,t){this._subscribers[e]&&this._subscribers[e].forEach(function(e){e.apply(this,t)})}};var ee=y,b=n(3),x=n.n(b),S=n(4),C=n(5),te=n.n(C);function w(e){return(w=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e})(e)}function T(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),n.push.apply(n,r)}return n}function ne(e){for(var t=1;t<arguments.length;t++){var n=arguments[t]==null?{}:arguments[t];t%2?T(Object(n),!0).forEach(function(t){re(e,t,n[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(n)):T(Object(n)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(n,t))})}return e}function re(e,t,n){return(t=(function(e){var t=(function(e,t){if(w(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(w(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)})(e,`string`);return w(t)==`symbol`?t:t+``})(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function ie(e,t){var n=typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(!n){if(Array.isArray(e)||(n=E(e))||t&&e&&typeof e.length==`number`){n&&(e=n);var r=0,i=function(){};return{s:i,n:function(){return r>=e.length?{done:!0}:{done:!1,value:e[r++]}},e:function(e){throw e},f:i}}throw TypeError(`Invalid attempt to iterate non-iterable instance.
|
|
10
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}var a,o=!0,s=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return o=e.done,e},e:function(e){s=!0,a=e},f:function(){try{o||n.return==null||n.return()}finally{if(s)throw a}}}}function ae(e,t){return(function(e){if(Array.isArray(e))return e})(e)||(function(e,t){var n=e==null?null:typeof Symbol<`u`&&e[Symbol.iterator]||e[`@@iterator`];if(n!=null){var r,i,a,o,s=[],c=!0,l=!1;try{if(a=(n=n.call(e)).next,t===0){if(Object(n)!==n)return;c=!1}else for(;!(c=(r=a.call(n)).done)&&(s.push(r.value),s.length!==t);c=!0);}catch(e){l=!0,i=e}finally{try{if(!c&&n.return!=null&&(o=n.return(),Object(o)!==o))return}finally{if(l)throw i}}return s}})(e,t)||E(e,t)||(function(){throw TypeError(`Invalid attempt to destructure non-iterable instance.
|
|
11
|
+
In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)})()}function E(e,t){if(e){if(typeof e==`string`)return D(e,t);var n={}.toString.call(e).slice(8,-1);return n===`Object`&&e.constructor&&(n=e.constructor.name),n===`Map`||n===`Set`?Array.from(e):n===`Arguments`||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?D(e,t):void 0}}function D(e,t){(t==null||t>e.length)&&(t=e.length);for(var n=0,r=Array(t);n<t;n++)r[n]=e[n];return r}function oe(){for(var e=/(?:[0]{1,2}[:-]){5}[0]{1,2}/,t=i.a.networkInterfaces(),n=0,r=Object.entries(t);n<r.length;n++){var a=ae(r[n],2),o=(a[0],a[1]);if(o){var s,c=ie(o);try{for(c.s();!(s=c.n()).done;){var l=s.value;if(!1===e.test(l.mac))return l.mac}}catch(e){c.e(e)}finally{c.f()}}}return`00:00:00:00:00:00`}var O,k,A=(O=process.version,{os:i.a.type(),os_version:i.a.release(),app_name:`node`,app_version:O,device_id:te.a.createHash(`md5`).update(oe()).digest(`hex`),platform:`node`}),j=(0,S.promisify)(x.a.resolve);function M(e){this._offlineQueue=[],e.endpoint=e.endpoint||`gm.mmstat.com`,ee.call(this,ne(ne({},A),e)),this._config.endpoint_url=`https://${this._config.endpoint}/aes.1.1`}M.prototype=((k=function(){}).prototype=ee.prototype,new k),M.prototype.constructor=M,M.prototype.send=function(e){var t,n=this;return(t=this._config.endpoint,j(t)).then(function(t){return n._offlineQueue.forEach(function(e){n.send(e)}),n._offlineQueue=[],n._print(`send`,e),o()(n._config.endpoint_url,{method:`POST`,keepalive:!0,body:JSON.stringify({gokey:encodeURIComponent(e),gmkey:`EXP`})}).catch(function(){})}).catch(function(t){n._offlineQueue.length>500&&n._offlineQueue.shift(),n._offlineQueue.push(e)})},t.default=M}]).default})),Jn=O(((e,t)=>{t.exports=(function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){typeof Symbol<`u`&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:`Module`}),Object.defineProperty(e,`__esModule`,{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t||4&t&&typeof e==`object`&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,`default`,{enumerable:!0,value:e}),2&t&&typeof e!=`string`)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,`a`,t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p=``,n(n.s=0)})([function(e,t,n){n.r(t);var r=[`ec`,`ea`,`el`,`et`],i=function(e,t){var n=function(e){var n=e.ec,r=e.ea,i=e.el,a=e.et,o=a===void 0?`CLK`:a,s=e.xpath;delete e.ec,delete e.ea,delete e.el,delete e.et,delete e.xpath,e.p1=n,e.p2=r,e.p3=i,e.p4=o,e.p5=s;try{t.log(`event`,e)}catch{}};return function(){var t=arguments,i={};if(t.length!==0){for(var a=0;a<t.length;a++){var o,s,c=t[a];if(a!==0&&typeof c==`object`&&a!==t.length-1)return void(e==null||(o=e.console)==null||(s=o.warn)==null||s.call(o,`Only the last argument can be object type`));if(typeof c==`string`||typeof c==`number`)i[r[a]]=c;else if(typeof c==`object`&&a===t.length-1)for(var l in c)c.hasOwnProperty(l)&&(i[l]=c[l])}n(i)}else{var u,d;(u=e.console)==null||(d=u.warn)==null||d.call(u,`At lease one augument`)}}};t.default=function(e,t){return i(global,e)}}]).default})),Yn=A(qn(),1),Xn=A(Jn(),1);const Zn=()=>p(I(),`telemetry.jsonl`);let Qn;const G=new Set;let K;try{let e=new Yn.default({pid:`bailian-cli-node`,env:Kn()}),t=e.send.bind(e);e.send=function(e){let n=t(e);if(n&&typeof n.then==`function`){let e=n;G.add(e),e.finally(()=>G.delete(e))}return n},K=e,Qn=e.use(Xn.default)}catch{}async function $n(e=1e3){try{if(K)try{typeof K._sendAll==`function`&&K._sendAll()}catch{}if(G.size===0)return;let t=[...G].map(e=>e.catch(()=>void 0));await Promise.race([Promise.allSettled(t),new Promise(t=>setTimeout(t,e).unref?.())])}catch{}}async function er(e){try{await R();let n=Zn();try{s(n).size>5242880&&c(n)}catch{}t(n,JSON.stringify(e)+`
|
|
12
|
+
`,{mode:384})}catch{}}async function tr(e){try{if(!Qn)return;Qn(e.command,Gn(e))}catch{}}const nr=new Set([`apiKey`,`baseUrl`,`output`,`quiet`,`verbose`,`timeout`,`noColor`,`yes`,`dryRun`,`help`,`nonInteractive`,`async`,`console`]),rr=new Set(`page.pageSize.n.count.model.voice.language.provider.capability.temperature.topP.topK.maxTokens.seed.stream.size.resolution.ratio.duration.format.audioFormat.sampleRate.pitch.rate.volume.api.mode.download.noWait.textOnly.promptExtend.enableSsml.watermark.hasThoughts.listTools.rerank.rerankTopN.diarization`.split(`.`));function ir(e){let t={};for(let[n,r]of Object.entries(e))n.startsWith(`_`)||nr.has(n)||rr.has(n)&&(r===void 0||r===!1||(t[n]=r));return t}async function ar(e,t,n,r){if(!e.telemetry){await r();return}let i=performance.now(),a=!0,o,s,c;try{await r()}catch(e){throw a=!1,e instanceof N?(o=e.message,s=e.api?.httpStatus,c=e.api?.requestId):e instanceof Error&&(o=e.message),e}finally{let r=Math.round(performance.now()-i),l;e.apiKey||e.fileApiKey?l=`api-key`:(e.accessTokenEnv||e.fileAccessToken)&&(l=`access-token`);let u=Un({command:t.join(` `),durationMs:r,success:a,error:a?void 0:{message:o,httpStatus:s,requestId:c},cliVersion:e.clientVersion??`unknown`,authMethod:l,params:ir(n)});er(u).catch(()=>{}),tr(u).catch(()=>{})}}function or(e){if(!e.model)return null;let t=e.inferenceMetadata;return{model:e.model,name:e.name??e.model,description:e.description??e.shortDescription??``,shortDescription:e.shortDescription,provider:e.provider??``,capabilities:e.capabilities??[],features:e.features??[],category:e.category,contextWindow:e.contextWindow??void 0,maxOutputTokens:e.maxOutputTokens??void 0,maxInputTokens:e.maxInputTokens??void 0,docUrl:e.docUrl,collectionTag:e.collectionTag,inferenceMetadata:t,prices:e.prices,qpmInfo:e.qpmInfo,versionTag:e.versionTag,openSource:e.openSource}}var sr=class{name=`api`;constructor(e){this.config=e}available(){return!0}async load(){let e=await Tt(this.config,``,{pageNo:1,pageSize:50}),t=[...e.models],n=Math.ceil(e.total/50);for(let e=2;e<=n;e++){let n=await Tt(this.config,``,{pageNo:e,pageSize:50});t.push(...n.models)}return t.map(or).filter(e=>e!==null)}};const cr=`models.jsonl`;function lr(){return T(I(),`skills/bailian-docs-llm-wiki`)}function ur(){return T(lr(),cr)}function dr(){return T(w(ne(import.meta.url)),`../../../../../skills/bailian-docs-llm-wiki/models`)}function fr(e){return!e.model||typeof e.model!=`string`?null:{model:e.model,name:e.name??e.model,description:e.description??``,provider:e.provider??``,capabilities:e.capabilities??[],features:e.features??[],contextWindow:e.contextWindow,maxOutputTokens:e.maxOutputTokens,docUrl:e.docUrl,inferenceMetadata:e.inferenceMetadata,shortDescription:e.shortDescription,category:e.category,collectionTag:e.collectionTag,maxInputTokens:e.maxInputTokens,prices:e.prices,qpmInfo:e.qpmInfo,versionTag:e.versionTag,openSource:e.openSource,family:e.family,familyName:e.familyName}}function pr(e){let t=S(e,`utf-8`).split(`
|
|
13
|
+
`).filter(Boolean),n=[];for(let e of t)try{let t=fr(JSON.parse(e));t&&n.push(t)}catch{}return n}function mr(){let e=dr();if(!b(T(e,cr)))return!1;let t=lr();try{return x(t,{recursive:!0}),ee(e,t,{recursive:!0}),!0}catch{return!1}}var hr=class{name=`catalog`;options;constructor(e){this.options=e??{}}available(){return b(ur())}async load(){return!this.available()&&(this.options.onPrepareStart?.(),!mr())?[]:pr(ur())}};async function gr(e,t){let n=[new hr({onPrepareStart:t?.onPrepareStart}),new sr(e)];for(let e of n)if(e.available()){let t=await e.load();if(t.length>0)return t}let r=await n[0].load();if(r.length>0)return r;throw new N(`No model data available.`,M.GENERAL)}const _r={Text:`Text`,Image:`Image`,Video:`Video`,Audio:`Audio`},q={Single:`single`,Pipeline:`pipeline`},vr={Low:`low`,Medium:`medium`,High:`high`},J={Standard:`standard`,Large:`large`,ExtraLarge:`extra-large`},Y={Flagship:`flagship`,Balanced:`balanced`,CostOptimized:`cost-optimized`},X={TG:`TG`,Reasoning:`Reasoning`,VU:`VU`,IG:`IG`,VG:`VG`,TTS:`TTS`,ASR:`ASR`,RealtimeASR:`Realtime-ASR`,RealtimeTTS:`Realtime-Text-to-Speech`,RealtimeAudioTranslate:`Realtime-Audio-Translate`,RealtimeOmni:`Realtime-Omni`,MultimodalOmni:`Multimodal-Omni`,ME:`ME`,TR:`TR`,ThreeDGeneration:`3D-generation`},yr={FunctionCalling:`function-calling`,WebSearch:`web-search`,StructuredOutputs:`structured-outputs`,PrefixCompletion:`prefix-completion`},br={Flagship:`Flagship`,CostOptimized:`Cost-optimized`},xr=`You are a model recommendation advisor for Alibaba Cloud Model Studio. From the candidate models below, select the best recommendations.
|
|
2464
14
|
|
|
2465
15
|
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights, step, summary — must be written in English.
|
|
2466
16
|
|
|
@@ -2501,8 +51,7 @@ Single task:
|
|
|
2501
51
|
{"type":"single","recommendations":[{"model":"model ID","reason":"recommendation reason","highlights":["key highlights"]}]}
|
|
2502
52
|
|
|
2503
53
|
Pipeline (only when confident multi-model is needed):
|
|
2504
|
-
{"type":"pipeline","summary":"one-line solution description","steps":[{"step":"step description","recommendations":[{"model":"model ID","reason":"reason for choosing","highlights":["highlights"]}]}]}
|
|
2505
|
-
const PIPELINE_SYSTEM_PROMPT = `You are a model recommendation advisor for Alibaba Cloud Model Studio. The user's need has been decomposed into multi-step pipeline. Select the best model for each step.
|
|
54
|
+
{"type":"pipeline","summary":"one-line solution description","steps":[{"step":"step description","recommendations":[{"model":"model ID","reason":"reason for choosing","highlights":["highlights"]}]}]}`,Sr=`You are a model recommendation advisor for Alibaba Cloud Model Studio. The user's need has been decomposed into multi-step pipeline. Select the best model for each step.
|
|
2506
55
|
|
|
2507
56
|
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights, step, summary — must be written in English.
|
|
2508
57
|
|
|
@@ -2541,8 +90,55 @@ Key principles:
|
|
|
2541
90
|
|
|
2542
91
|
Or (if single model suffices):
|
|
2543
92
|
{"type":"single","recommendations":[{"model":"model ID","reason":"recommendation reason","highlights":
|
|
2544
|
-
["key highlights"]}]}
|
|
2545
|
-
|
|
93
|
+
["key highlights"]}]}`,Z={complexity:q.Single,taskSummary:``,scenarioHints:[],inputModality:[],outputModality:[],requiredCapabilities:[X.TG],requiredFeatures:[],budget:vr.Medium,contextNeed:J.Standard,qualityPreference:Y.Balanced,confidence:0};async function Cr(e,t){let n=Me(e.baseUrl),r={model:`qwen-flash`,messages:[{role:`system`,content:`You are an intent analyzer. Given the user's requirement, understand the scenario first, then extract structured information.
|
|
94
|
+
|
|
95
|
+
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. All text fields (taskSummary, scenarioHints) must be in English.
|
|
96
|
+
|
|
97
|
+
## Analysis Steps
|
|
98
|
+
1. Summarize the user's core need in one sentence (taskSummary) — be specific about the scenario, not generic
|
|
99
|
+
2. Infer scenario hints (scenarioHints), e.g.: ["low-latency", "consumer-facing", "high-concurrency", "conversational", "offline-batch", "high-precision"]
|
|
100
|
+
3. Infer budget and qualityPreference from scenario hints
|
|
101
|
+
- Only deviate from defaults when the user explicitly states or the scenario strongly implies
|
|
102
|
+
- User says "low cost", "cheap", "save money" → budget:"low"
|
|
103
|
+
- User says "best", "high precision", "cost no object" → qualityPreference:"flagship"
|
|
104
|
+
- Infer from scenario constraints only when strong: e.g. "1M requests/day customer service" → budget:"low" (high concurrency = cost-sensitive)
|
|
105
|
+
- Otherwise keep budget:"medium", qualityPreference:"balanced"
|
|
106
|
+
4. Extract modalities, capabilities, features etc.
|
|
107
|
+
|
|
108
|
+
## Model preference detection
|
|
109
|
+
Analyze whether the user mentioned specific models, model families, or vendors:
|
|
110
|
+
- No models/families/vendors mentioned → mode:"unconstrained", no targets
|
|
111
|
+
- User scoped the range (e.g. "recommend from the deepseek family", "open-source reasoning models") → mode:"scoped", targets:["deepseek"]
|
|
112
|
+
- User wants to compare specific models (e.g. "compare wan2.6 and wan2.7", "is qwen-max good for legal analysis") → mode:"comparison", targets:["wan2.6","wan2.7"]
|
|
113
|
+
- Single model evaluation is also comparison with one target
|
|
114
|
+
- User wants alternatives to a reference model (e.g. "something like qwen-max but cheaper") → mode:"alternative", targets:["qwen-max"]
|
|
115
|
+
- User explicitly excludes certain models/families (e.g. "good models besides qwen") → excludes:["qwen"], mode determined by other signals
|
|
116
|
+
- targets should capture the model/family names as the user wrote them
|
|
117
|
+
|
|
118
|
+
## Output fields
|
|
119
|
+
- taskSummary: one-sentence scenario understanding (must be specific, never generic like "user wants AI")
|
|
120
|
+
- scenarioHints: array of inferred scenario features
|
|
121
|
+
- complexity: "single" or "pipeline"
|
|
122
|
+
- segments: only for pipeline, each with step/inputModality/outputModality/requiredCapabilities
|
|
123
|
+
- step must describe the specific problem this step solves in the user's task, no numbered or generic modal labels
|
|
124
|
+
- segments must form a modality chain: each step's inputModality should cover the previous step's outputModality
|
|
125
|
+
- inputModality: user input modalities ["Text","Image","Video","Audio"]
|
|
126
|
+
- outputModality: expected output modalities
|
|
127
|
+
- requiredCapabilities: capability codes (use strictly from the list, don't invent):
|
|
128
|
+
TG=Text Generation, Reasoning=Reasoning, VU=Vision Understanding, IG=Image Generation, VG=Video Generation,
|
|
129
|
+
TTS=Text-to-Speech, ASR=Speech-to-Text, Realtime-ASR=Realtime Speech-to-Text,
|
|
130
|
+
Realtime-Text-to-Speech=Realtime Text-to-Speech, Realtime-Audio-Translate=Realtime Audio Translation,
|
|
131
|
+
Realtime-Omni=Realtime Omni-modal, Multimodal-Omni=Multimodal Omni, ME=Multimodal Embedding,
|
|
132
|
+
TR=Translation, 3D-generation=3D Generation
|
|
133
|
+
- requiredFeatures: required features (function-calling, web-search, structured-outputs, prefix-completion)
|
|
134
|
+
- budget: "low"/"medium"/"high"
|
|
135
|
+
- contextNeed: "standard"/"large"/"extra-large"
|
|
136
|
+
- qualityPreference: "flagship"/"balanced"/"cost-optimized"
|
|
137
|
+
- modelPreference: { mode, targets?, excludes? }
|
|
138
|
+
|
|
139
|
+
Output only JSON, no other text.`},{role:`user`,content:t}],max_tokens:1024,temperature:0};try{let t=((await B(e,{url:n,method:`POST`,body:r,timeout:5e3})).choices?.[0]?.message?.content??``).match(/\{[\s\S]*\}/);if(!t)return Z;let i=JSON.parse(t[0]),a=[`scoped`,`comparison`,`alternative`],o=i.modelPreference,s=o&&typeof o==`object`?{mode:a.includes(o.mode)?o.mode:`unconstrained`,targets:Array.isArray(o.targets)?o.targets:void 0,excludes:Array.isArray(o.excludes)?o.excludes:void 0}:void 0;return{complexity:i.complexity===q.Pipeline?q.Pipeline:q.Single,taskSummary:typeof i.taskSummary==`string`?i.taskSummary:``,scenarioHints:Array.isArray(i.scenarioHints)?i.scenarioHints:[],segments:Array.isArray(i.segments)?i.segments.map(e=>({step:e.step??``,inputModality:Array.isArray(e.inputModality)?e.inputModality:[],outputModality:Array.isArray(e.outputModality)?e.outputModality:[],requiredCapabilities:Array.isArray(e.requiredCapabilities)?e.requiredCapabilities:[]})):void 0,inputModality:Array.isArray(i.inputModality)?i.inputModality:[],outputModality:Array.isArray(i.outputModality)?i.outputModality:[],requiredCapabilities:Array.isArray(i.requiredCapabilities)?i.requiredCapabilities:[],requiredFeatures:Array.isArray(i.requiredFeatures)?i.requiredFeatures:[],budget:i.budget??Z.budget,contextNeed:i.contextNeed??Z.contextNeed,qualityPreference:i.qualityPreference??Z.qualityPreference,confidence:1,modelPreference:s}}catch{return Z}}const wr=/-\d{4}-\d{2}-\d{2}$/,Tr=new Set([X.IG,X.VG,X.TTS,X.RealtimeTTS,X.ThreeDGeneration]),Er=new Set([X.TG,X.Reasoning,X.ASR,X.RealtimeASR,X.RealtimeAudioTranslate,X.TR,X.ME]),Dr={standard:0,large:32e3,"extra-large":128e3};function Or(e){let t=!1,n=!1;for(let r of e)Tr.has(r)&&(t=!0),Er.has(r)&&(n=!0);return t&&n}function kr(e){let t=new Set(e.map(({model:e})=>e));return e.filter(({model:e})=>{let n=e.replace(wr,``);return n===e?!0:!t.has(n)})}function Ar(e,t,n){let r=e.inferenceMetadata?.request_modality??[],i=e.inferenceMetadata?.response_modality??[];return!(t.length>0&&!t.some(e=>r.includes(e))||n.length>0&&!n.some(e=>i.includes(e)))}function jr(e,t){if(t.length===0)return!0;let n=e.inferenceMetadata?.request_modality??[];return t.some(e=>n.includes(e))}function Mr(e,t){let{requiredCapabilities:n,requiredFeatures:r,contextNeed:i,qualityPreference:a}=t,{capabilities:o,features:s,contextWindow:c,category:l}=e,u=0;for(let e of n)o.includes(e)&&(u+=10);for(let e of r)s.includes(e)&&(u+=5);let d=Dr[i];return d>0&&(c??0)>=d&&(u+=8),a===Y.Flagship&&l===br.Flagship||a===Y.CostOptimized&&l===br.CostOptimized?u+=15:a===Y.Balanced&&l===br.Flagship&&(u+=5),u}function Q(e,t,n){return e.map(e=>({model:e,score:Mr(e,t)})).sort((e,t)=>t.score-e.score).slice(0,n)}function Nr(e){return new Set(e.map(({model:e})=>e.model))}function Pr(e,t){let n=new Map,r=[],i=[];for(let a of e){let e=a.model.family;if(!e){r.push(a);continue}let o=n.get(e)??0;o<t?(r.push(a),n.set(e,o+1)):i.push(a)}return r.length>=10?r:[...r,...i.slice(0,10-r.length)]}function Fr(e,t){let n=new Set(t);return e.filter(e=>n.has(e.model.model)?!1:(n.add(e.model.model),!0))}function Ir(e,t,n){return n.size>=10?[]:Q(e.filter(({model:e})=>!n.has(e)),t,10-n.size)}function Lr(e,t,n,r,i){let{inputModality:a,outputModality:o,requiredCapabilities:s}=t,c={complexity:q.Single,taskSummary:``,scenarioHints:[],inputModality:a,outputModality:o,requiredCapabilities:s,requiredFeatures:[],budget:r,contextNeed:J.Standard,qualityPreference:i,confidence:1},l=e.filter(e=>Ar(e,a,o)&&jr(e,n));return l.length<5&&(l=e.filter(e=>Ar(e,a,o))),l.length<5&&(l=e),Q(l,c,5)}function Rr(e,t){e=kr(e);let n;if(t.complexity===q.Pipeline&&t.segments?.length){let r=[];for(let[n,i]of t.segments.entries()){let a=n===0?[]:t.segments[n-1].outputModality,o=Fr(Lr(e,i,a,t.budget,t.qualityPreference),Nr(r));r=[...r,...o]}let i=Ir(e,t,Nr(r));n=[...r,...i]}else if(Or(t.requiredCapabilities))n=zr(e,t);else{let r=e.filter(e=>Ar(e,t.inputModality,t.outputModality));r.length<5&&(r=e),n=Q(r,t,50)}return Pr(n,3)}function zr(e,t){let n=t.requiredCapabilities.filter(e=>Tr.has(e)),r=t.requiredCapabilities.filter(e=>Er.has(e)),i=[];if(n.length>0&&(i=Q(e.filter(e=>n.some(t=>e.capabilities.includes(t))),t,25)),r.length>0){let n=Nr(i),a={...t,requiredCapabilities:r},o=e.filter(e=>!n.has(e.model)&&r.some(t=>e.capabilities.includes(t)));i=[...i,...Q(o,a,25)]}let a=Ir(e,t,Nr(i));return[...i,...a]}const Br=`text-embedding-v4`;function Vr(){return T(I(),`skills/bailian-docs-llm-wiki`)}function Hr(){return T(Vr(),`models-embeddings.json`)}function Ur(){let e=Hr();if(!b(e))return null;try{return JSON.parse(S(e,`utf-8`)).items}catch{return null}}async function Wr(e,t){return(await B(e,{url:`${e.baseUrl}/compatible-mode/v1/embeddings`,method:`POST`,body:{model:Br,input:[t],dimensions:512,encoding_format:`float`},timeout:1e4})).data[0].embedding}async function Gr(e,t){return(await B(e,{url:`${e.baseUrl}/compatible-mode/v1/embeddings`,method:`POST`,body:{model:Br,input:t,dimensions:512,encoding_format:`float`},timeout:3e4})).data.sort((e,t)=>e.index-t.index).map(e=>e.embedding)}const Kr={TG:`Text Generation`,Reasoning:`Reasoning`,VU:`Vision Understanding`,IG:`Image Generation`,VG:`Video Generation`,TTS:`Text-to-Speech`,ASR:`Speech-to-Text`},qr={Text:`Text`,Image:`Image`,Video:`Video`,Audio:`Audio`};function Jr(){let e=T(Vr(),`groups`),t=new Map;if(!b(e))return t;for(let n of C(e).filter(e=>e.endsWith(`.json`)))try{let r=JSON.parse(S(T(e,n),`utf-8`)),i=r.description??``;if(r.items)for(let e of r.items)t.set(e.model,e.description||i)}catch{}return t}function Yr(e,t){let n=(e.capabilities??[]).map(e=>Kr[e]??e).join(`, `),r=t.get(e.model)||e.shortDescription||e.description||``,i=(e.inferenceMetadata?.request_modality??[]).map(e=>qr[e]??e).join(`, `),a=(e.inferenceMetadata?.response_modality??[]).map(e=>qr[e]??e).join(`, `);return[e.name,e.model,r,n?`Capabilities: ${n}`:``,i?`Input: ${i}`:``,a?`Output: ${a}`:``,e.features?.length?`Features: ${e.features.join(`, `)}`:``,e.familyName||``,e.category?`Category: ${e.category}`:``].filter(Boolean).join(` | `)}async function Xr(e,t){let n=Jr(),r=t.map(e=>Yr(e,n)),i=[];for(let t=0;t<r.length;t+=10){let n=await Gr(e,r.slice(t,t+10));i.push(...n)}let a=t.map((e,t)=>({id:e.model,vector:i[t]})),o={model:Br,dimensions:512,count:a.length,items:a},s=Hr();return x(w(s),{recursive:!0}),te(s,JSON.stringify(o)),a}function Zr(e,t){let n=0,r=0,i=0;for(let a=0;a<e.length;a++)n+=e[a]*t[a],r+=e[a]*e[a],i+=t[a]*t[a];let a=Math.sqrt(r)*Math.sqrt(i);return a===0?0:n/a}let Qr=null;function $r(){return Qr===null&&(Qr=Ur()),Qr}function ei(){return $r()!==null}function ti(e,t){let n=t.toLowerCase();return[e.model,e.name,e.family,e.familyName,e.provider].some(e=>e?.toLowerCase().includes(n))}function ni(e,t){return t.some(t=>ti(e,t))}function ri(e,t){return t.length===0?e:e.filter(({model:e})=>!ni(e,t))}function ii(e,t){let n=e.inferenceMetadata?.request_modality??[],r=e.inferenceMetadata?.response_modality??[],i=t.inputModality.length===0||t.inputModality.some(e=>n.includes(e)),a=t.outputModality.length===0||t.outputModality.some(e=>r.includes(e));return!i||!a?!1:t.requiredCapabilities.length===0?!0:t.requiredCapabilities.some(t=>e.capabilities.includes(t))}function $(e,t,n,r){return e.filter(e=>n.has(e.id)).map(e=>({id:e.id,similarity:Zr(t,e.vector)})).sort((e,t)=>t.similarity-e.similarity).slice(0,r)}function ai(e,t,n,r,i){let a=r.targets??[],o=a.length>0?e.filter(e=>ni(e,a)):e,s=o.length>=5?o:e,c=$(t,n,new Set(s.map(e=>e.model)),i),l=new Map(e.map(e=>[e.model,e])),u=[];if(o.length<5&&a.length>0){for(let e of o)u.push({model:e,score:1});let e=new Set(u.map(({model:e})=>e.model));for(let{id:t,similarity:n}of c){if(e.has(t))continue;let r=l.get(t);if(r&&u.push({model:r,score:n}),u.length>=i)break}return u}for(let{id:e,similarity:t}of c){let n=l.get(e);n&&u.push({model:n,score:t})}return u}function oi(e,t,n,r,i){let a=r.targets??[],o=new Map(e.map(e=>[e.model,e])),s=[],c=new Set;for(let t of e)ni(t,a)&&!c.has(t.model)&&(s.push({model:t,score:1}),c.add(t.model));let l=i-s.length;if(l>0){let r=$(t,n,new Set(e.filter(e=>!c.has(e.model)).map(e=>e.model)),l);for(let{id:e,similarity:t}of r){let n=o.get(e);n&&s.push({model:n,score:t})}}return s}function si(e,t,n,r,i){let a=r.targets??[],o=new Map(e.map(e=>[e.model,e])),s=e.filter(e=>ni(e,a)),c=new Set(s.map(e=>e.family).filter(Boolean)),l=[],u=new Set;for(let e of s)l.push({model:e,score:1}),u.add(e.model);let d=e.filter(e=>!u.has(e.model)&&(!e.family||!c.has(e.family))),f=$(t,n,new Set(d.map(e=>e.model)),i-l.length);for(let{id:e,similarity:t}of f){let n=o.get(e);n&&l.push({model:n,score:t})}return l}async function ci(e,t,n,r,i){let a=$r();a||(a=await Xr(e,t),Qr=a);let o=await Wr(e,n),s=new Map(t.map(e=>[e.model,e])),c=i?.modelPreference,l=c?.excludes??[];if(c&&c.mode!==`unconstrained`){let e;switch(c.mode){case`scoped`:e=ai(t,a,o,c,r);break;case`comparison`:e=oi(t,a,o,c,r);break;case`alternative`:e=si(t,a,o,c,r);break;default:e=[]}return ri(e,l)}if(i?.complexity===q.Pipeline&&i.segments?.length){let e=new Set,n=[],c=Math.max(5,Math.ceil(r/i.segments.length));for(let r of i.segments){let i=t.filter(e=>ii(e,r)),l=new Set(i.filter(t=>!e.has(t.model)).map(e=>e.model));if(l.size===0)continue;let u=$(a,o,l,c);for(let{id:t,similarity:r}of u){let i=s.get(t);i&&!e.has(t)&&(n.push({model:i,score:r}),e.add(t))}}return ri(n,l)}let u=new Set(t.map(e=>e.model)),d=$(a,o,u,r),f=[];for(let{id:e,similarity:t}of d){let n=s.get(e);n&&f.push({model:n,score:t})}return ri(f,l)}function li(e){if(e.prices?.length)return e.prices.map(e=>`${e.type}:${e.price}/${e.unit}`).join(`, `)}function ui(e){if(!e.qpmInfo)return;let t=Object.entries(e.qpmInfo);if(t.length!==0)return t.map(([e,t])=>`${e}:${t.count_limit}/${t.count_limit_period}s`).join(`, `)}function di(e){return e.map(({model:e})=>{let t=[`ID: ${e.model}`,`Name: ${e.name}`,`Description: ${e.shortDescription||e.description}`,`Capabilities: ${e.capabilities.join(`, `)}`,`Features: ${e.features.join(`, `)}`];e.contextWindow&&t.push(`Context Window: ${e.contextWindow}`),e.maxOutputTokens&&t.push(`Max Output: ${e.maxOutputTokens}`),e.category&&t.push(`Category: ${e.category}`);let n=e.inferenceMetadata;n?.request_modality?.length&&t.push(`Input Modality: ${n.request_modality.join(`, `)}`),n?.response_modality?.length&&t.push(`Output Modality: ${n.response_modality.join(`, `)}`);let r=li(e);r&&t.push(`Pricing: ${r}`);let i=ui(e);return i&&t.push(`QPM: ${i}`),e.versionTag&&t.push(`Version: ${e.versionTag}`),e.openSource!==void 0&&t.push(`Open Source: ${e.openSource?`Yes`:`No`}`),e.family&&t.push(`Family: ${e.family}`),t.join(` | `)}).join(`
|
|
140
|
+
`)}function fi(e){let{taskSummary:t,scenarioHints:n,inputModality:r,outputModality:i,requiredCapabilities:a,requiredFeatures:o,budget:s,qualityPreference:c,contextNeed:l,segments:u,modelPreference:d}=e,f=[];if(t&&f.push(`Task: ${t}`),n.length&&f.push(`Scenario: ${n.join(`, `)}`),r.length&&f.push(`Input: ${r.join(`, `)}`),i.length&&f.push(`Output: ${i.join(`, `)}`),a.length&&f.push(`Capabilities: ${a.join(`, `)}`),o.length&&f.push(`Features: ${o.join(`, `)}`),f.push(`Budget: ${s}`),f.push(`Quality: ${c}`),l!==J.Standard&&f.push(`Context: ${l}`),d&&d.mode!==`unconstrained`&&(f.push(`Mode: ${d.mode}`),d.targets?.length&&f.push(`Targets: ${d.targets.join(`, `)}`),d.excludes?.length&&f.push(`Excludes: ${d.excludes.join(`, `)}`)),u?.length){f.push(`Pipeline Steps:`);for(let e of u){let t=e.inputModality.join(`,`)||`none`,n=e.outputModality.join(`,`)||`none`,r=e.requiredCapabilities.join(`,`)||`none`;f.push(` - ${e.step} (Input: ${t} → Output: ${n}, Capabilities: ${r})`)}}return f.join(`
|
|
141
|
+
`)}function pi(e){if(!e)return;let t=e.match(/\/(\d+)\.html/);if(t)return`https://bailian.console.aliyun.com/cn-beijing?tab=doc#/doc/?type=model&url=${t[1]}`}function mi(e,t,n){let r=Array.isArray(e)?e:[],i=[],a=new Set;for(let e of r){let r=t.get(e.model);if(!r||r.family&&a.has(r.family))continue;r.family&&a.add(r.family);let{model:o,name:s,category:c,contextWindow:l,maxOutputTokens:u,docUrl:d}=r;if(i.push({model:o,name:s,reason:e.reason??``,highlights:e.highlights??[],category:c,contextWindow:l,maxOutputTokens:u,docUrl:d}),i.length>=n)break}return i}function hi(e,t){for(let n=1;n<e.length;n++){let r=e[n-1],i=e[n],a=new Set(r.recommendations.flatMap(e=>t.get(e.model)?.inferenceMetadata?.response_modality??[]));if(a.size===0)continue;let o=[];for(let e of i.recommendations){let n=t.get(e.model)?.inferenceMetadata?.request_modality??[];!n.some(e=>a.has(e))&&n.length>0&&o.push(`${e.name}'s input modalities [${n.join(`, `)}] may not be compatible with the previous step's output modalities [${[...a].join(`, `)}]`)}o.length>0&&(i.warnings=o)}}async function gi(e,t,n,r,i,a){let o=di(t),s=fi(n),c=n.modelPreference?.mode,l;if(c===`comparison`)l=`You are a model comparison advisor for Alibaba Cloud Model Studio. The user wants to compare specific models — analyze them against the use case.
|
|
2546
142
|
|
|
2547
143
|
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights — must be written in English.
|
|
2548
144
|
|
|
@@ -2563,8 +159,7 @@ The intent's modelPreference.targets are the models to compare.
|
|
|
2563
159
|
- Output strict JSON
|
|
2564
160
|
|
|
2565
161
|
## Output Format
|
|
2566
|
-
{"type":"single","recommendations":[{"model":"model ID","reason":"comparative analysis","highlights":["differentiators"]}]}`;
|
|
2567
|
-
const ALTERNATIVE_SYSTEM_PROMPT = `You are a model alternative advisor for Alibaba Cloud Model Studio. The user has a reference model and wants to find alternatives.
|
|
162
|
+
{"type":"single","recommendations":[{"model":"model ID","reason":"comparative analysis","highlights":["differentiators"]}]}`;else if(c===`alternative`)l=`You are a model alternative advisor for Alibaba Cloud Model Studio. The user has a reference model and wants to find alternatives.
|
|
2568
163
|
|
|
2569
164
|
CRITICAL: You MUST respond entirely in English. Do not use any Chinese characters anywhere in your response. Every field — reason, highlights — must be written in English.
|
|
2570
165
|
|
|
@@ -2585,770 +180,4 @@ The intent's modelPreference.targets is the reference model.
|
|
|
2585
180
|
- Output strict JSON
|
|
2586
181
|
|
|
2587
182
|
## Output Format
|
|
2588
|
-
{"type":"single","recommendations":[{"model":"model ID","reason":"alternative analysis","highlights":["differentiators"]}]}`;
|
|
2589
|
-
//#endregion
|
|
2590
|
-
//#region src/advisor/constants/defaults.ts
|
|
2591
|
-
const DEFAULT_INTENT = {
|
|
2592
|
-
complexity: Complexities.Single,
|
|
2593
|
-
taskSummary: "",
|
|
2594
|
-
scenarioHints: [],
|
|
2595
|
-
inputModality: [],
|
|
2596
|
-
outputModality: [],
|
|
2597
|
-
requiredCapabilities: [Capabilities.TG],
|
|
2598
|
-
requiredFeatures: [],
|
|
2599
|
-
budget: Budgets.Medium,
|
|
2600
|
-
contextNeed: ContextNeeds.Standard,
|
|
2601
|
-
qualityPreference: QualityPreferences.Balanced,
|
|
2602
|
-
confidence: 0
|
|
2603
|
-
};
|
|
2604
|
-
//#endregion
|
|
2605
|
-
//#region src/advisor/intent.ts
|
|
2606
|
-
async function analyzeIntent(config, input) {
|
|
2607
|
-
const url = chatEndpoint(config.baseUrl);
|
|
2608
|
-
const body = {
|
|
2609
|
-
model: INTENT_MODEL,
|
|
2610
|
-
messages: [{
|
|
2611
|
-
role: "system",
|
|
2612
|
-
content: INTENT_SYSTEM_PROMPT
|
|
2613
|
-
}, {
|
|
2614
|
-
role: "user",
|
|
2615
|
-
content: input
|
|
2616
|
-
}],
|
|
2617
|
-
max_tokens: 1024,
|
|
2618
|
-
temperature: 0
|
|
2619
|
-
};
|
|
2620
|
-
try {
|
|
2621
|
-
const jsonMatch = ((await requestJson(config, {
|
|
2622
|
-
url,
|
|
2623
|
-
method: "POST",
|
|
2624
|
-
body,
|
|
2625
|
-
timeout: 5e3
|
|
2626
|
-
})).choices?.[0]?.message?.content ?? "").match(/\{[\s\S]*\}/);
|
|
2627
|
-
if (!jsonMatch) return DEFAULT_INTENT;
|
|
2628
|
-
const parsed = JSON.parse(jsonMatch[0]);
|
|
2629
|
-
const VALID_MODES = [
|
|
2630
|
-
"scoped",
|
|
2631
|
-
"comparison",
|
|
2632
|
-
"alternative"
|
|
2633
|
-
];
|
|
2634
|
-
const rawPref = parsed.modelPreference;
|
|
2635
|
-
const modelPreference = rawPref && typeof rawPref === "object" ? {
|
|
2636
|
-
mode: VALID_MODES.includes(rawPref.mode) ? rawPref.mode : "unconstrained",
|
|
2637
|
-
targets: Array.isArray(rawPref.targets) ? rawPref.targets : void 0,
|
|
2638
|
-
excludes: Array.isArray(rawPref.excludes) ? rawPref.excludes : void 0
|
|
2639
|
-
} : void 0;
|
|
2640
|
-
return {
|
|
2641
|
-
complexity: parsed.complexity === Complexities.Pipeline ? Complexities.Pipeline : Complexities.Single,
|
|
2642
|
-
taskSummary: typeof parsed.taskSummary === "string" ? parsed.taskSummary : "",
|
|
2643
|
-
scenarioHints: Array.isArray(parsed.scenarioHints) ? parsed.scenarioHints : [],
|
|
2644
|
-
segments: Array.isArray(parsed.segments) ? parsed.segments.map((seg) => ({
|
|
2645
|
-
step: seg.step ?? "",
|
|
2646
|
-
inputModality: Array.isArray(seg.inputModality) ? seg.inputModality : [],
|
|
2647
|
-
outputModality: Array.isArray(seg.outputModality) ? seg.outputModality : [],
|
|
2648
|
-
requiredCapabilities: Array.isArray(seg.requiredCapabilities) ? seg.requiredCapabilities : []
|
|
2649
|
-
})) : void 0,
|
|
2650
|
-
inputModality: Array.isArray(parsed.inputModality) ? parsed.inputModality : [],
|
|
2651
|
-
outputModality: Array.isArray(parsed.outputModality) ? parsed.outputModality : [],
|
|
2652
|
-
requiredCapabilities: Array.isArray(parsed.requiredCapabilities) ? parsed.requiredCapabilities : [],
|
|
2653
|
-
requiredFeatures: Array.isArray(parsed.requiredFeatures) ? parsed.requiredFeatures : [],
|
|
2654
|
-
budget: parsed.budget ?? DEFAULT_INTENT.budget,
|
|
2655
|
-
contextNeed: parsed.contextNeed ?? DEFAULT_INTENT.contextNeed,
|
|
2656
|
-
qualityPreference: parsed.qualityPreference ?? DEFAULT_INTENT.qualityPreference,
|
|
2657
|
-
confidence: 1,
|
|
2658
|
-
modelPreference
|
|
2659
|
-
};
|
|
2660
|
-
} catch {
|
|
2661
|
-
return DEFAULT_INTENT;
|
|
2662
|
-
}
|
|
2663
|
-
}
|
|
2664
|
-
//#endregion
|
|
2665
|
-
//#region src/advisor/constants/scoring.ts
|
|
2666
|
-
const SNAPSHOT_DATE_RE = /-\d{4}-\d{2}-\d{2}$/;
|
|
2667
|
-
const GENERATION_CAPS = new Set([
|
|
2668
|
-
Capabilities.IG,
|
|
2669
|
-
Capabilities.VG,
|
|
2670
|
-
Capabilities.TTS,
|
|
2671
|
-
Capabilities.RealtimeTTS,
|
|
2672
|
-
Capabilities.ThreeDGeneration
|
|
2673
|
-
]);
|
|
2674
|
-
const TEXT_CAPS = new Set([
|
|
2675
|
-
Capabilities.TG,
|
|
2676
|
-
Capabilities.Reasoning,
|
|
2677
|
-
Capabilities.ASR,
|
|
2678
|
-
Capabilities.RealtimeASR,
|
|
2679
|
-
Capabilities.RealtimeAudioTranslate,
|
|
2680
|
-
Capabilities.TR,
|
|
2681
|
-
Capabilities.ME
|
|
2682
|
-
]);
|
|
2683
|
-
const CONTEXT_THRESHOLDS = {
|
|
2684
|
-
standard: 0,
|
|
2685
|
-
large: 32e3,
|
|
2686
|
-
"extra-large": 128e3
|
|
2687
|
-
};
|
|
2688
|
-
//#endregion
|
|
2689
|
-
//#region src/advisor/recall.ts
|
|
2690
|
-
function hasMultiDomainCapabilities(caps) {
|
|
2691
|
-
let hasGen = false;
|
|
2692
|
-
let hasText = false;
|
|
2693
|
-
for (const cap of caps) {
|
|
2694
|
-
if (GENERATION_CAPS.has(cap)) hasGen = true;
|
|
2695
|
-
if (TEXT_CAPS.has(cap)) hasText = true;
|
|
2696
|
-
}
|
|
2697
|
-
return hasGen && hasText;
|
|
2698
|
-
}
|
|
2699
|
-
function deduplicateSnapshots(models) {
|
|
2700
|
-
const mainModels = new Set(models.map(({ model }) => model));
|
|
2701
|
-
return models.filter(({ model }) => {
|
|
2702
|
-
const base = model.replace(SNAPSHOT_DATE_RE, "");
|
|
2703
|
-
if (base === model) return true;
|
|
2704
|
-
return !mainModels.has(base);
|
|
2705
|
-
});
|
|
2706
|
-
}
|
|
2707
|
-
function matchesModality(model, inputModality, outputModality) {
|
|
2708
|
-
const modelInput = model.inferenceMetadata?.request_modality ?? [];
|
|
2709
|
-
const modelOutput = model.inferenceMetadata?.response_modality ?? [];
|
|
2710
|
-
if (inputModality.length > 0) {
|
|
2711
|
-
if (!inputModality.some((mod) => modelInput.includes(mod))) return false;
|
|
2712
|
-
}
|
|
2713
|
-
if (outputModality.length > 0) {
|
|
2714
|
-
if (!outputModality.some((mod) => modelOutput.includes(mod))) return false;
|
|
2715
|
-
}
|
|
2716
|
-
return true;
|
|
2717
|
-
}
|
|
2718
|
-
function matchesUpstream(model, upstreamOutput) {
|
|
2719
|
-
if (upstreamOutput.length === 0) return true;
|
|
2720
|
-
const accepts = model.inferenceMetadata?.request_modality ?? [];
|
|
2721
|
-
return upstreamOutput.some((mod) => accepts.includes(mod));
|
|
2722
|
-
}
|
|
2723
|
-
function scoreModel(model, intent) {
|
|
2724
|
-
const { requiredCapabilities, requiredFeatures, contextNeed, qualityPreference } = intent;
|
|
2725
|
-
const { capabilities, features, contextWindow, category } = model;
|
|
2726
|
-
let score = 0;
|
|
2727
|
-
for (const cap of requiredCapabilities) if (capabilities.includes(cap)) score += 10;
|
|
2728
|
-
for (const feat of requiredFeatures) if (features.includes(feat)) score += 5;
|
|
2729
|
-
const ctxThreshold = CONTEXT_THRESHOLDS[contextNeed];
|
|
2730
|
-
if (ctxThreshold > 0 && (contextWindow ?? 0) >= ctxThreshold) score += 8;
|
|
2731
|
-
if (qualityPreference === QualityPreferences.Flagship && category === ModelCategories.Flagship) score += 15;
|
|
2732
|
-
else if (qualityPreference === QualityPreferences.CostOptimized && category === ModelCategories.CostOptimized) score += 15;
|
|
2733
|
-
else if (qualityPreference === QualityPreferences.Balanced) {
|
|
2734
|
-
if (category === ModelCategories.Flagship) score += 5;
|
|
2735
|
-
}
|
|
2736
|
-
return score;
|
|
2737
|
-
}
|
|
2738
|
-
function scoreAndRank(models, intent, limit) {
|
|
2739
|
-
return models.map((model) => ({
|
|
2740
|
-
model,
|
|
2741
|
-
score: scoreModel(model, intent)
|
|
2742
|
-
})).sort((left, right) => right.score - left.score).slice(0, limit);
|
|
2743
|
-
}
|
|
2744
|
-
function candidateIds(candidates) {
|
|
2745
|
-
return new Set(candidates.map(({ model }) => model.model));
|
|
2746
|
-
}
|
|
2747
|
-
function capByFamily(candidates, cap) {
|
|
2748
|
-
const counts = /* @__PURE__ */ new Map();
|
|
2749
|
-
const kept = [];
|
|
2750
|
-
const overflow = [];
|
|
2751
|
-
for (const candidate of candidates) {
|
|
2752
|
-
const family = candidate.model.family;
|
|
2753
|
-
if (!family) {
|
|
2754
|
-
kept.push(candidate);
|
|
2755
|
-
continue;
|
|
2756
|
-
}
|
|
2757
|
-
const cur = counts.get(family) ?? 0;
|
|
2758
|
-
if (cur < cap) {
|
|
2759
|
-
kept.push(candidate);
|
|
2760
|
-
counts.set(family, cur + 1);
|
|
2761
|
-
} else overflow.push(candidate);
|
|
2762
|
-
}
|
|
2763
|
-
if (kept.length >= 10) return kept;
|
|
2764
|
-
return [...kept, ...overflow.slice(0, 10 - kept.length)];
|
|
2765
|
-
}
|
|
2766
|
-
function deduplicateCandidates(candidates, excludeIds) {
|
|
2767
|
-
const seen = new Set(excludeIds);
|
|
2768
|
-
return candidates.filter((candidate) => {
|
|
2769
|
-
if (seen.has(candidate.model.model)) return false;
|
|
2770
|
-
seen.add(candidate.model.model);
|
|
2771
|
-
return true;
|
|
2772
|
-
});
|
|
2773
|
-
}
|
|
2774
|
-
function computeRemaining(models, intent, excludeIds) {
|
|
2775
|
-
if (excludeIds.size >= 10) return [];
|
|
2776
|
-
return scoreAndRank(models.filter(({ model }) => !excludeIds.has(model)), intent, 10 - excludeIds.size);
|
|
2777
|
-
}
|
|
2778
|
-
function recallForSegment(models, segment, upstreamOutput, budget, qualityPreference) {
|
|
2779
|
-
const { inputModality, outputModality, requiredCapabilities } = segment;
|
|
2780
|
-
const segmentIntent = {
|
|
2781
|
-
complexity: Complexities.Single,
|
|
2782
|
-
taskSummary: "",
|
|
2783
|
-
scenarioHints: [],
|
|
2784
|
-
inputModality,
|
|
2785
|
-
outputModality,
|
|
2786
|
-
requiredCapabilities,
|
|
2787
|
-
requiredFeatures: [],
|
|
2788
|
-
budget,
|
|
2789
|
-
contextNeed: ContextNeeds.Standard,
|
|
2790
|
-
qualityPreference,
|
|
2791
|
-
confidence: 1
|
|
2792
|
-
};
|
|
2793
|
-
let candidates = models.filter((profile) => matchesModality(profile, inputModality, outputModality) && matchesUpstream(profile, upstreamOutput));
|
|
2794
|
-
if (candidates.length < 5) candidates = models.filter((profile) => matchesModality(profile, inputModality, outputModality));
|
|
2795
|
-
if (candidates.length < 5) candidates = models;
|
|
2796
|
-
return scoreAndRank(candidates, segmentIntent, 5);
|
|
2797
|
-
}
|
|
2798
|
-
function recallCandidates(models, intent) {
|
|
2799
|
-
models = deduplicateSnapshots(models);
|
|
2800
|
-
let result;
|
|
2801
|
-
if (intent.complexity === Complexities.Pipeline && intent.segments?.length) {
|
|
2802
|
-
let results = [];
|
|
2803
|
-
for (const [segIdx, segment] of intent.segments.entries()) {
|
|
2804
|
-
const upstreamOutput = segIdx === 0 ? [] : intent.segments[segIdx - 1].outputModality;
|
|
2805
|
-
const unique = deduplicateCandidates(recallForSegment(models, segment, upstreamOutput, intent.budget, intent.qualityPreference), candidateIds(results));
|
|
2806
|
-
results = [...results, ...unique];
|
|
2807
|
-
}
|
|
2808
|
-
const remaining = computeRemaining(models, intent, candidateIds(results));
|
|
2809
|
-
result = [...results, ...remaining];
|
|
2810
|
-
} else if (hasMultiDomainCapabilities(intent.requiredCapabilities)) result = recallCrossDomain(models, intent);
|
|
2811
|
-
else {
|
|
2812
|
-
let hardFiltered = models.filter((profile) => matchesModality(profile, intent.inputModality, intent.outputModality));
|
|
2813
|
-
if (hardFiltered.length < 5) hardFiltered = models;
|
|
2814
|
-
result = scoreAndRank(hardFiltered, intent, 50);
|
|
2815
|
-
}
|
|
2816
|
-
return capByFamily(result, 3);
|
|
2817
|
-
}
|
|
2818
|
-
function recallCrossDomain(models, intent) {
|
|
2819
|
-
const perDomain = Math.ceil(50 / 2);
|
|
2820
|
-
const genCaps = intent.requiredCapabilities.filter((cap) => GENERATION_CAPS.has(cap));
|
|
2821
|
-
const textCaps = intent.requiredCapabilities.filter((cap) => TEXT_CAPS.has(cap));
|
|
2822
|
-
let results = [];
|
|
2823
|
-
if (genCaps.length > 0) results = scoreAndRank(models.filter((profile) => genCaps.some((cap) => profile.capabilities.includes(cap))), intent, perDomain);
|
|
2824
|
-
if (textCaps.length > 0) {
|
|
2825
|
-
const excludeIds = candidateIds(results);
|
|
2826
|
-
const textIntent = {
|
|
2827
|
-
...intent,
|
|
2828
|
-
requiredCapabilities: textCaps
|
|
2829
|
-
};
|
|
2830
|
-
const textModels = models.filter((profile) => !excludeIds.has(profile.model) && textCaps.some((cap) => profile.capabilities.includes(cap)));
|
|
2831
|
-
results = [...results, ...scoreAndRank(textModels, textIntent, perDomain)];
|
|
2832
|
-
}
|
|
2833
|
-
const remaining = computeRemaining(models, intent, candidateIds(results));
|
|
2834
|
-
return [...results, ...remaining];
|
|
2835
|
-
}
|
|
2836
|
-
//#endregion
|
|
2837
|
-
//#region src/advisor/embedding.ts
|
|
2838
|
-
const EMBEDDING_MODEL = "text-embedding-v4";
|
|
2839
|
-
const EMBEDDINGS_FILE = "models-embeddings.json";
|
|
2840
|
-
const BATCH_SIZE = 10;
|
|
2841
|
-
function skillDataDir() {
|
|
2842
|
-
return join$1(getConfigDir(), "skills/doc-llm-wiki");
|
|
2843
|
-
}
|
|
2844
|
-
function embeddingsPath() {
|
|
2845
|
-
return join$1(skillDataDir(), EMBEDDINGS_FILE);
|
|
2846
|
-
}
|
|
2847
|
-
function loadModelEmbeddings() {
|
|
2848
|
-
const path = embeddingsPath();
|
|
2849
|
-
if (!existsSync$1(path)) return null;
|
|
2850
|
-
try {
|
|
2851
|
-
return JSON.parse(readFileSync$1(path, "utf-8")).items;
|
|
2852
|
-
} catch {
|
|
2853
|
-
return null;
|
|
2854
|
-
}
|
|
2855
|
-
}
|
|
2856
|
-
async function embedQuery(config, text) {
|
|
2857
|
-
return (await requestJson(config, {
|
|
2858
|
-
url: `${config.baseUrl}/compatible-mode/v1/embeddings`,
|
|
2859
|
-
method: "POST",
|
|
2860
|
-
body: {
|
|
2861
|
-
model: EMBEDDING_MODEL,
|
|
2862
|
-
input: [text],
|
|
2863
|
-
dimensions: 512,
|
|
2864
|
-
encoding_format: "float"
|
|
2865
|
-
},
|
|
2866
|
-
timeout: 1e4
|
|
2867
|
-
})).data[0].embedding;
|
|
2868
|
-
}
|
|
2869
|
-
async function embedBatch(config, texts) {
|
|
2870
|
-
return (await requestJson(config, {
|
|
2871
|
-
url: `${config.baseUrl}/compatible-mode/v1/embeddings`,
|
|
2872
|
-
method: "POST",
|
|
2873
|
-
body: {
|
|
2874
|
-
model: EMBEDDING_MODEL,
|
|
2875
|
-
input: texts,
|
|
2876
|
-
dimensions: 512,
|
|
2877
|
-
encoding_format: "float"
|
|
2878
|
-
},
|
|
2879
|
-
timeout: 3e4
|
|
2880
|
-
})).data.sort((left, right) => left.index - right.index).map((item) => item.embedding);
|
|
2881
|
-
}
|
|
2882
|
-
const CAPABILITY_LABELS = {
|
|
2883
|
-
TG: "Text Generation",
|
|
2884
|
-
Reasoning: "Reasoning",
|
|
2885
|
-
VU: "Vision Understanding",
|
|
2886
|
-
IG: "Image Generation",
|
|
2887
|
-
VG: "Video Generation",
|
|
2888
|
-
TTS: "Text-to-Speech",
|
|
2889
|
-
ASR: "Speech-to-Text"
|
|
2890
|
-
};
|
|
2891
|
-
const MODALITY_LABELS = {
|
|
2892
|
-
Text: "Text",
|
|
2893
|
-
Image: "Image",
|
|
2894
|
-
Video: "Video",
|
|
2895
|
-
Audio: "Audio"
|
|
2896
|
-
};
|
|
2897
|
-
function loadGroupDescriptions() {
|
|
2898
|
-
const groupsDir = join$1(skillDataDir(), "groups");
|
|
2899
|
-
const map = /* @__PURE__ */ new Map();
|
|
2900
|
-
if (!existsSync$1(groupsDir)) return map;
|
|
2901
|
-
for (const file of readdirSync(groupsDir).filter((name) => name.endsWith(".json"))) try {
|
|
2902
|
-
const data = JSON.parse(readFileSync$1(join$1(groupsDir, file), "utf-8"));
|
|
2903
|
-
const groupDesc = data.description ?? "";
|
|
2904
|
-
if (data.items) for (const item of data.items) map.set(item.model, item.description || groupDesc);
|
|
2905
|
-
} catch {}
|
|
2906
|
-
return map;
|
|
2907
|
-
}
|
|
2908
|
-
function buildModelText(model, descriptions) {
|
|
2909
|
-
const caps = (model.capabilities ?? []).map((cap) => CAPABILITY_LABELS[cap] ?? cap).join(", ");
|
|
2910
|
-
const description = descriptions.get(model.model) || model.shortDescription || model.description || "";
|
|
2911
|
-
const inputMods = (model.inferenceMetadata?.request_modality ?? []).map((mod) => MODALITY_LABELS[mod] ?? mod).join(", ");
|
|
2912
|
-
const outputMods = (model.inferenceMetadata?.response_modality ?? []).map((mod) => MODALITY_LABELS[mod] ?? mod).join(", ");
|
|
2913
|
-
return [
|
|
2914
|
-
model.name,
|
|
2915
|
-
model.model,
|
|
2916
|
-
description,
|
|
2917
|
-
caps ? `Capabilities: ${caps}` : "",
|
|
2918
|
-
inputMods ? `Input: ${inputMods}` : "",
|
|
2919
|
-
outputMods ? `Output: ${outputMods}` : "",
|
|
2920
|
-
model.features?.length ? `Features: ${model.features.join(", ")}` : "",
|
|
2921
|
-
model.familyName || "",
|
|
2922
|
-
model.category ? `Category: ${model.category}` : ""
|
|
2923
|
-
].filter(Boolean).join(" | ");
|
|
2924
|
-
}
|
|
2925
|
-
async function buildAndCacheEmbeddings(config, models) {
|
|
2926
|
-
const descriptions = loadGroupDescriptions();
|
|
2927
|
-
const texts = models.map((profile) => buildModelText(profile, descriptions));
|
|
2928
|
-
const allVectors = [];
|
|
2929
|
-
for (let batchStart = 0; batchStart < texts.length; batchStart += BATCH_SIZE) {
|
|
2930
|
-
const vectors = await embedBatch(config, texts.slice(batchStart, batchStart + BATCH_SIZE));
|
|
2931
|
-
allVectors.push(...vectors);
|
|
2932
|
-
}
|
|
2933
|
-
const items = models.map((profile, idx) => ({
|
|
2934
|
-
id: profile.model,
|
|
2935
|
-
vector: allVectors[idx]
|
|
2936
|
-
}));
|
|
2937
|
-
const output = {
|
|
2938
|
-
model: EMBEDDING_MODEL,
|
|
2939
|
-
dimensions: 512,
|
|
2940
|
-
count: items.length,
|
|
2941
|
-
items
|
|
2942
|
-
};
|
|
2943
|
-
const outPath = embeddingsPath();
|
|
2944
|
-
mkdirSync$1(dirname(outPath), { recursive: true });
|
|
2945
|
-
writeFileSync$1(outPath, JSON.stringify(output));
|
|
2946
|
-
return items;
|
|
2947
|
-
}
|
|
2948
|
-
function cosineSimilarity(vecA, vecB) {
|
|
2949
|
-
let dot = 0;
|
|
2950
|
-
let normA = 0;
|
|
2951
|
-
let normB = 0;
|
|
2952
|
-
for (let idx = 0; idx < vecA.length; idx++) {
|
|
2953
|
-
dot += vecA[idx] * vecB[idx];
|
|
2954
|
-
normA += vecA[idx] * vecA[idx];
|
|
2955
|
-
normB += vecB[idx] * vecB[idx];
|
|
2956
|
-
}
|
|
2957
|
-
const denom = Math.sqrt(normA) * Math.sqrt(normB);
|
|
2958
|
-
return denom === 0 ? 0 : dot / denom;
|
|
2959
|
-
}
|
|
2960
|
-
//#endregion
|
|
2961
|
-
//#region src/advisor/recall-semantic.ts
|
|
2962
|
-
let cachedEmbeddings = null;
|
|
2963
|
-
function getEmbeddings() {
|
|
2964
|
-
if (cachedEmbeddings === null) cachedEmbeddings = loadModelEmbeddings();
|
|
2965
|
-
return cachedEmbeddings;
|
|
2966
|
-
}
|
|
2967
|
-
function isSemanticAvailable() {
|
|
2968
|
-
return getEmbeddings() !== null;
|
|
2969
|
-
}
|
|
2970
|
-
function matchesTarget(model, target) {
|
|
2971
|
-
const needle = target.toLowerCase();
|
|
2972
|
-
return [
|
|
2973
|
-
model.model,
|
|
2974
|
-
model.name,
|
|
2975
|
-
model.family,
|
|
2976
|
-
model.familyName,
|
|
2977
|
-
model.provider
|
|
2978
|
-
].some((field) => field?.toLowerCase().includes(needle));
|
|
2979
|
-
}
|
|
2980
|
-
function matchesAnyTarget(model, targets) {
|
|
2981
|
-
return targets.some((target) => matchesTarget(model, target));
|
|
2982
|
-
}
|
|
2983
|
-
function applyExcludes(candidates, excludes) {
|
|
2984
|
-
if (excludes.length === 0) return candidates;
|
|
2985
|
-
return candidates.filter(({ model }) => !matchesAnyTarget(model, excludes));
|
|
2986
|
-
}
|
|
2987
|
-
function matchesSegment(model, segment) {
|
|
2988
|
-
const modelIn = model.inferenceMetadata?.request_modality ?? [];
|
|
2989
|
-
const modelOut = model.inferenceMetadata?.response_modality ?? [];
|
|
2990
|
-
const inOk = segment.inputModality.length === 0 || segment.inputModality.some((mod) => modelIn.includes(mod));
|
|
2991
|
-
const outOk = segment.outputModality.length === 0 || segment.outputModality.some((mod) => modelOut.includes(mod));
|
|
2992
|
-
if (!inOk || !outOk) return false;
|
|
2993
|
-
if (segment.requiredCapabilities.length === 0) return true;
|
|
2994
|
-
return segment.requiredCapabilities.some((cap) => model.capabilities.includes(cap));
|
|
2995
|
-
}
|
|
2996
|
-
function rankByEmbedding(embeddings, queryVector, allowedIds, topK) {
|
|
2997
|
-
return embeddings.filter((item) => allowedIds.has(item.id)).map((item) => ({
|
|
2998
|
-
id: item.id,
|
|
2999
|
-
similarity: cosineSimilarity(queryVector, item.vector)
|
|
3000
|
-
})).sort((left, right) => right.similarity - left.similarity).slice(0, topK);
|
|
3001
|
-
}
|
|
3002
|
-
function recallScoped(models, embeddings, queryVector, preference, topK) {
|
|
3003
|
-
const targets = preference.targets ?? [];
|
|
3004
|
-
const scopedModels = targets.length > 0 ? models.filter((profile) => matchesAnyTarget(profile, targets)) : models;
|
|
3005
|
-
const MIN_SCOPED = 5;
|
|
3006
|
-
const pool = scopedModels.length >= MIN_SCOPED ? scopedModels : models;
|
|
3007
|
-
const scored = rankByEmbedding(embeddings, queryVector, new Set(pool.map((profile) => profile.model)), topK);
|
|
3008
|
-
const modelMap = new Map(models.map((profile) => [profile.model, profile]));
|
|
3009
|
-
const results = [];
|
|
3010
|
-
if (scopedModels.length < MIN_SCOPED && targets.length > 0) {
|
|
3011
|
-
for (const profile of scopedModels) results.push({
|
|
3012
|
-
model: profile,
|
|
3013
|
-
score: 1
|
|
3014
|
-
});
|
|
3015
|
-
const seen = new Set(results.map(({ model }) => model.model));
|
|
3016
|
-
for (const { id, similarity } of scored) {
|
|
3017
|
-
if (seen.has(id)) continue;
|
|
3018
|
-
const model = modelMap.get(id);
|
|
3019
|
-
if (model) results.push({
|
|
3020
|
-
model,
|
|
3021
|
-
score: similarity
|
|
3022
|
-
});
|
|
3023
|
-
if (results.length >= topK) break;
|
|
3024
|
-
}
|
|
3025
|
-
return results;
|
|
3026
|
-
}
|
|
3027
|
-
for (const { id, similarity } of scored) {
|
|
3028
|
-
const model = modelMap.get(id);
|
|
3029
|
-
if (model) results.push({
|
|
3030
|
-
model,
|
|
3031
|
-
score: similarity
|
|
3032
|
-
});
|
|
3033
|
-
}
|
|
3034
|
-
return results;
|
|
3035
|
-
}
|
|
3036
|
-
function recallComparison(models, embeddings, queryVector, preference, topK) {
|
|
3037
|
-
const targets = preference.targets ?? [];
|
|
3038
|
-
const modelMap = new Map(models.map((profile) => [profile.model, profile]));
|
|
3039
|
-
const forced = [];
|
|
3040
|
-
const forcedIds = /* @__PURE__ */ new Set();
|
|
3041
|
-
for (const profile of models) if (matchesAnyTarget(profile, targets) && !forcedIds.has(profile.model)) {
|
|
3042
|
-
forced.push({
|
|
3043
|
-
model: profile,
|
|
3044
|
-
score: 1
|
|
3045
|
-
});
|
|
3046
|
-
forcedIds.add(profile.model);
|
|
3047
|
-
}
|
|
3048
|
-
const remaining = topK - forced.length;
|
|
3049
|
-
if (remaining > 0) {
|
|
3050
|
-
const extra = rankByEmbedding(embeddings, queryVector, new Set(models.filter((profile) => !forcedIds.has(profile.model)).map((profile) => profile.model)), remaining);
|
|
3051
|
-
for (const { id, similarity } of extra) {
|
|
3052
|
-
const model = modelMap.get(id);
|
|
3053
|
-
if (model) forced.push({
|
|
3054
|
-
model,
|
|
3055
|
-
score: similarity
|
|
3056
|
-
});
|
|
3057
|
-
}
|
|
3058
|
-
}
|
|
3059
|
-
return forced;
|
|
3060
|
-
}
|
|
3061
|
-
function recallAlternative(models, embeddings, queryVector, preference, topK) {
|
|
3062
|
-
const targets = preference.targets ?? [];
|
|
3063
|
-
const modelMap = new Map(models.map((profile) => [profile.model, profile]));
|
|
3064
|
-
const refModels = models.filter((profile) => matchesAnyTarget(profile, targets));
|
|
3065
|
-
const refFamilies = new Set(refModels.map((profile) => profile.family).filter(Boolean));
|
|
3066
|
-
const results = [];
|
|
3067
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3068
|
-
for (const profile of refModels) {
|
|
3069
|
-
results.push({
|
|
3070
|
-
model: profile,
|
|
3071
|
-
score: 1
|
|
3072
|
-
});
|
|
3073
|
-
seen.add(profile.model);
|
|
3074
|
-
}
|
|
3075
|
-
const altPool = models.filter((profile) => !seen.has(profile.model) && (!profile.family || !refFamilies.has(profile.family)));
|
|
3076
|
-
const scored = rankByEmbedding(embeddings, queryVector, new Set(altPool.map((profile) => profile.model)), topK - results.length);
|
|
3077
|
-
for (const { id, similarity } of scored) {
|
|
3078
|
-
const model = modelMap.get(id);
|
|
3079
|
-
if (model) results.push({
|
|
3080
|
-
model,
|
|
3081
|
-
score: similarity
|
|
3082
|
-
});
|
|
3083
|
-
}
|
|
3084
|
-
return results;
|
|
3085
|
-
}
|
|
3086
|
-
async function recallSemantic(config, models, query, topK, intent) {
|
|
3087
|
-
let embeddings = getEmbeddings();
|
|
3088
|
-
if (!embeddings) {
|
|
3089
|
-
embeddings = await buildAndCacheEmbeddings(config, models);
|
|
3090
|
-
cachedEmbeddings = embeddings;
|
|
3091
|
-
}
|
|
3092
|
-
const queryVector = await embedQuery(config, query);
|
|
3093
|
-
const modelMap = new Map(models.map((profile) => [profile.model, profile]));
|
|
3094
|
-
const preference = intent?.modelPreference;
|
|
3095
|
-
const excludes = preference?.excludes ?? [];
|
|
3096
|
-
if (preference && preference.mode !== "unconstrained") {
|
|
3097
|
-
let results;
|
|
3098
|
-
switch (preference.mode) {
|
|
3099
|
-
case "scoped":
|
|
3100
|
-
results = recallScoped(models, embeddings, queryVector, preference, topK);
|
|
3101
|
-
break;
|
|
3102
|
-
case "comparison":
|
|
3103
|
-
results = recallComparison(models, embeddings, queryVector, preference, topK);
|
|
3104
|
-
break;
|
|
3105
|
-
case "alternative":
|
|
3106
|
-
results = recallAlternative(models, embeddings, queryVector, preference, topK);
|
|
3107
|
-
break;
|
|
3108
|
-
default: results = [];
|
|
3109
|
-
}
|
|
3110
|
-
return applyExcludes(results, excludes);
|
|
3111
|
-
}
|
|
3112
|
-
if (intent?.complexity === Complexities.Pipeline && intent.segments?.length) {
|
|
3113
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3114
|
-
const results = [];
|
|
3115
|
-
const perSegment = Math.max(5, Math.ceil(topK / intent.segments.length));
|
|
3116
|
-
for (const segment of intent.segments) {
|
|
3117
|
-
const matched = models.filter((profile) => matchesSegment(profile, segment));
|
|
3118
|
-
const allowedIds = new Set(matched.filter((profile) => !seen.has(profile.model)).map((profile) => profile.model));
|
|
3119
|
-
if (allowedIds.size === 0) continue;
|
|
3120
|
-
const scored = rankByEmbedding(embeddings, queryVector, allowedIds, perSegment);
|
|
3121
|
-
for (const { id, similarity } of scored) {
|
|
3122
|
-
const model = modelMap.get(id);
|
|
3123
|
-
if (model && !seen.has(id)) {
|
|
3124
|
-
results.push({
|
|
3125
|
-
model,
|
|
3126
|
-
score: similarity
|
|
3127
|
-
});
|
|
3128
|
-
seen.add(id);
|
|
3129
|
-
}
|
|
3130
|
-
}
|
|
3131
|
-
}
|
|
3132
|
-
return applyExcludes(results, excludes);
|
|
3133
|
-
}
|
|
3134
|
-
const allIds = new Set(models.map((profile) => profile.model));
|
|
3135
|
-
const scored = rankByEmbedding(embeddings, queryVector, allIds, topK);
|
|
3136
|
-
const results = [];
|
|
3137
|
-
for (const { id, similarity } of scored) {
|
|
3138
|
-
const model = modelMap.get(id);
|
|
3139
|
-
if (model) results.push({
|
|
3140
|
-
model,
|
|
3141
|
-
score: similarity
|
|
3142
|
-
});
|
|
3143
|
-
}
|
|
3144
|
-
return applyExcludes(results, excludes);
|
|
3145
|
-
}
|
|
3146
|
-
//#endregion
|
|
3147
|
-
//#region src/advisor/recommend.ts
|
|
3148
|
-
function formatPrices(profile) {
|
|
3149
|
-
if (!profile.prices?.length) return void 0;
|
|
3150
|
-
return profile.prices.map((price) => `${price.type}:${price.price}/${price.unit}`).join(", ");
|
|
3151
|
-
}
|
|
3152
|
-
function formatQpm(profile) {
|
|
3153
|
-
if (!profile.qpmInfo) return void 0;
|
|
3154
|
-
const entries = Object.entries(profile.qpmInfo);
|
|
3155
|
-
if (entries.length === 0) return void 0;
|
|
3156
|
-
return entries.map(([key, limit]) => `${key}:${limit.count_limit}/${limit.count_limit_period}s`).join(", ");
|
|
3157
|
-
}
|
|
3158
|
-
function buildCandidatesContext(candidates) {
|
|
3159
|
-
return candidates.map(({ model: profile }) => {
|
|
3160
|
-
const parts = [
|
|
3161
|
-
`ID: ${profile.model}`,
|
|
3162
|
-
`Name: ${profile.name}`,
|
|
3163
|
-
`Description: ${profile.shortDescription || profile.description}`,
|
|
3164
|
-
`Capabilities: ${profile.capabilities.join(", ")}`,
|
|
3165
|
-
`Features: ${profile.features.join(", ")}`
|
|
3166
|
-
];
|
|
3167
|
-
if (profile.contextWindow) parts.push(`Context Window: ${profile.contextWindow}`);
|
|
3168
|
-
if (profile.maxOutputTokens) parts.push(`Max Output: ${profile.maxOutputTokens}`);
|
|
3169
|
-
if (profile.category) parts.push(`Category: ${profile.category}`);
|
|
3170
|
-
const modality = profile.inferenceMetadata;
|
|
3171
|
-
if (modality?.request_modality?.length) parts.push(`Input Modality: ${modality.request_modality.join(", ")}`);
|
|
3172
|
-
if (modality?.response_modality?.length) parts.push(`Output Modality: ${modality.response_modality.join(", ")}`);
|
|
3173
|
-
const prices = formatPrices(profile);
|
|
3174
|
-
if (prices) parts.push(`Pricing: ${prices}`);
|
|
3175
|
-
const qpm = formatQpm(profile);
|
|
3176
|
-
if (qpm) parts.push(`QPM: ${qpm}`);
|
|
3177
|
-
if (profile.versionTag) parts.push(`Version: ${profile.versionTag}`);
|
|
3178
|
-
if (profile.openSource !== void 0) parts.push(`Open Source: ${profile.openSource ? "Yes" : "No"}`);
|
|
3179
|
-
if (profile.family) parts.push(`Family: ${profile.family}`);
|
|
3180
|
-
return parts.join(" | ");
|
|
3181
|
-
}).join("\n");
|
|
3182
|
-
}
|
|
3183
|
-
function buildIntentContext(intent) {
|
|
3184
|
-
const { taskSummary, scenarioHints, inputModality, outputModality, requiredCapabilities, requiredFeatures, budget, qualityPreference, contextNeed, segments, modelPreference } = intent;
|
|
3185
|
-
const parts = [];
|
|
3186
|
-
if (taskSummary) parts.push(`Task: ${taskSummary}`);
|
|
3187
|
-
if (scenarioHints.length) parts.push(`Scenario: ${scenarioHints.join(", ")}`);
|
|
3188
|
-
if (inputModality.length) parts.push(`Input: ${inputModality.join(", ")}`);
|
|
3189
|
-
if (outputModality.length) parts.push(`Output: ${outputModality.join(", ")}`);
|
|
3190
|
-
if (requiredCapabilities.length) parts.push(`Capabilities: ${requiredCapabilities.join(", ")}`);
|
|
3191
|
-
if (requiredFeatures.length) parts.push(`Features: ${requiredFeatures.join(", ")}`);
|
|
3192
|
-
parts.push(`Budget: ${budget}`);
|
|
3193
|
-
parts.push(`Quality: ${qualityPreference}`);
|
|
3194
|
-
if (contextNeed !== ContextNeeds.Standard) parts.push(`Context: ${contextNeed}`);
|
|
3195
|
-
if (modelPreference && modelPreference.mode !== "unconstrained") {
|
|
3196
|
-
parts.push(`Mode: ${modelPreference.mode}`);
|
|
3197
|
-
if (modelPreference.targets?.length) parts.push(`Targets: ${modelPreference.targets.join(", ")}`);
|
|
3198
|
-
if (modelPreference.excludes?.length) parts.push(`Excludes: ${modelPreference.excludes.join(", ")}`);
|
|
3199
|
-
}
|
|
3200
|
-
if (segments?.length) {
|
|
3201
|
-
parts.push(`Pipeline Steps:`);
|
|
3202
|
-
for (const seg of segments) {
|
|
3203
|
-
const inMod = seg.inputModality.join(",") || "none";
|
|
3204
|
-
const outMod = seg.outputModality.join(",") || "none";
|
|
3205
|
-
const caps = seg.requiredCapabilities.join(",") || "none";
|
|
3206
|
-
parts.push(` - ${seg.step} (Input: ${inMod} → Output: ${outMod}, Capabilities: ${caps})`);
|
|
3207
|
-
}
|
|
3208
|
-
}
|
|
3209
|
-
return parts.join("\n");
|
|
3210
|
-
}
|
|
3211
|
-
function buildDocLink(docUrl) {
|
|
3212
|
-
if (!docUrl) return void 0;
|
|
3213
|
-
const match = docUrl.match(/\/(\d+)\.html/);
|
|
3214
|
-
if (!match) return void 0;
|
|
3215
|
-
return `https://bailian.console.aliyun.com/cn-beijing?tab=doc#/doc/?type=model&url=${match[1]}`;
|
|
3216
|
-
}
|
|
3217
|
-
function buildRecommendations(items, modelMap, limit) {
|
|
3218
|
-
const list = Array.isArray(items) ? items : [];
|
|
3219
|
-
const recommendations = [];
|
|
3220
|
-
const seenFamilies = /* @__PURE__ */ new Set();
|
|
3221
|
-
for (const item of list) {
|
|
3222
|
-
const profile = modelMap.get(item.model);
|
|
3223
|
-
if (!profile) continue;
|
|
3224
|
-
if (profile.family && seenFamilies.has(profile.family)) continue;
|
|
3225
|
-
if (profile.family) seenFamilies.add(profile.family);
|
|
3226
|
-
const { model, name, category, contextWindow, maxOutputTokens, docUrl } = profile;
|
|
3227
|
-
recommendations.push({
|
|
3228
|
-
model,
|
|
3229
|
-
name,
|
|
3230
|
-
reason: item.reason ?? "",
|
|
3231
|
-
highlights: item.highlights ?? [],
|
|
3232
|
-
category,
|
|
3233
|
-
contextWindow,
|
|
3234
|
-
maxOutputTokens,
|
|
3235
|
-
docUrl
|
|
3236
|
-
});
|
|
3237
|
-
if (recommendations.length >= limit) break;
|
|
3238
|
-
}
|
|
3239
|
-
return recommendations;
|
|
3240
|
-
}
|
|
3241
|
-
function validatePipelineCompatibility(steps, modelMap) {
|
|
3242
|
-
for (let stepIdx = 1; stepIdx < steps.length; stepIdx++) {
|
|
3243
|
-
const prevStep = steps[stepIdx - 1];
|
|
3244
|
-
const currStep = steps[stepIdx];
|
|
3245
|
-
const prevOutputs = new Set(prevStep.recommendations.flatMap((rec) => {
|
|
3246
|
-
return modelMap.get(rec.model)?.inferenceMetadata?.response_modality ?? [];
|
|
3247
|
-
}));
|
|
3248
|
-
if (prevOutputs.size === 0) continue;
|
|
3249
|
-
const warnings = [];
|
|
3250
|
-
for (const rec of currStep.recommendations) {
|
|
3251
|
-
const accepts = modelMap.get(rec.model)?.inferenceMetadata?.request_modality ?? [];
|
|
3252
|
-
if (!accepts.some((mod) => prevOutputs.has(mod)) && accepts.length > 0) warnings.push(`${rec.name}'s input modalities [${accepts.join(", ")}] may not be compatible with the previous step's output modalities [${[...prevOutputs].join(", ")}]`);
|
|
3253
|
-
}
|
|
3254
|
-
if (warnings.length > 0) currStep.warnings = warnings;
|
|
3255
|
-
}
|
|
3256
|
-
}
|
|
3257
|
-
async function rankModels(config, candidates, intent, userInput, top, options) {
|
|
3258
|
-
const candidatesContext = buildCandidatesContext(candidates);
|
|
3259
|
-
const intentContext = buildIntentContext(intent);
|
|
3260
|
-
const preferenceMode = intent.modelPreference?.mode;
|
|
3261
|
-
let systemPrompt;
|
|
3262
|
-
if (preferenceMode === "comparison") systemPrompt = COMPARISON_SYSTEM_PROMPT;
|
|
3263
|
-
else if (preferenceMode === "alternative") systemPrompt = ALTERNATIVE_SYSTEM_PROMPT;
|
|
3264
|
-
else if (preferenceMode === "scoped") {
|
|
3265
|
-
const scopeNote = intent.modelPreference?.targets?.length ? `\n\n## Scope Restriction\nThe user explicitly requested recommendations from: ${intent.modelPreference.targets.join(", ")}. Prioritize models within this scope.` : "";
|
|
3266
|
-
systemPrompt = (intent.complexity === Complexities.Pipeline ? PIPELINE_SYSTEM_PROMPT : SINGLE_SYSTEM_PROMPT) + scopeNote;
|
|
3267
|
-
} else systemPrompt = intent.complexity === Complexities.Pipeline ? PIPELINE_SYSTEM_PROMPT : SINGLE_SYSTEM_PROMPT;
|
|
3268
|
-
const useThinkingModel = options?.enableThinking ?? false;
|
|
3269
|
-
const userMessage = intent.complexity === Complexities.Pipeline ? `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models for each pipeline step. Respond in English only.` : `Intent Analysis:\n${intentContext}\n\nCandidate Models:\n${candidatesContext}\n\nUser Request: ${userInput}\n\nRecommend up to ${top} models. Respond in English only.`;
|
|
3270
|
-
const body = {
|
|
3271
|
-
model: useThinkingModel ? RANKING_MODEL : RANKING_MODEL_FAST,
|
|
3272
|
-
messages: [{
|
|
3273
|
-
role: "system",
|
|
3274
|
-
content: systemPrompt
|
|
3275
|
-
}, {
|
|
3276
|
-
role: "user",
|
|
3277
|
-
content: userMessage
|
|
3278
|
-
}],
|
|
3279
|
-
max_tokens: 4096,
|
|
3280
|
-
temperature: 0
|
|
3281
|
-
};
|
|
3282
|
-
if (useThinkingModel) {
|
|
3283
|
-
body.stream = true;
|
|
3284
|
-
body.enable_thinking = true;
|
|
3285
|
-
}
|
|
3286
|
-
const url = chatEndpoint(config.baseUrl);
|
|
3287
|
-
let content;
|
|
3288
|
-
if (useThinkingModel) {
|
|
3289
|
-
const res = await request(config, {
|
|
3290
|
-
url,
|
|
3291
|
-
method: "POST",
|
|
3292
|
-
body,
|
|
3293
|
-
stream: true
|
|
3294
|
-
});
|
|
3295
|
-
let accumulated = "";
|
|
3296
|
-
let contentStarted = false;
|
|
3297
|
-
for await (const event of parseSSE(res)) {
|
|
3298
|
-
if (event.data === "[DONE]") break;
|
|
3299
|
-
try {
|
|
3300
|
-
const parsed = JSON.parse(event.data);
|
|
3301
|
-
for (const choice of parsed.choices) {
|
|
3302
|
-
const delta = choice.delta;
|
|
3303
|
-
if (delta.reasoning_content && options?.onThinking) options.onThinking(delta.reasoning_content);
|
|
3304
|
-
if (delta.content) {
|
|
3305
|
-
if (!contentStarted) {
|
|
3306
|
-
contentStarted = true;
|
|
3307
|
-
options?.onContentStart?.();
|
|
3308
|
-
}
|
|
3309
|
-
accumulated += delta.content;
|
|
3310
|
-
}
|
|
3311
|
-
}
|
|
3312
|
-
} catch {}
|
|
3313
|
-
}
|
|
3314
|
-
content = accumulated || "{}";
|
|
3315
|
-
} else content = (await requestJson(config, {
|
|
3316
|
-
url,
|
|
3317
|
-
method: "POST",
|
|
3318
|
-
body
|
|
3319
|
-
})).choices?.[0]?.message?.content ?? "{}";
|
|
3320
|
-
let parsed;
|
|
3321
|
-
try {
|
|
3322
|
-
const jsonMatch = content.match(/\{[\s\S]*\}/);
|
|
3323
|
-
parsed = JSON.parse(jsonMatch?.[0] ?? "{}");
|
|
3324
|
-
} catch {
|
|
3325
|
-
return {
|
|
3326
|
-
type: Complexities.Single,
|
|
3327
|
-
recommendations: []
|
|
3328
|
-
};
|
|
3329
|
-
}
|
|
3330
|
-
const modelMap = new Map(candidates.map(({ model: profile }) => [profile.model, profile]));
|
|
3331
|
-
if (parsed.type === Complexities.Pipeline && Array.isArray(parsed.steps)) {
|
|
3332
|
-
const steps = [];
|
|
3333
|
-
for (const rawStep of parsed.steps) {
|
|
3334
|
-
const recs = buildRecommendations(rawStep.recommendations ?? (rawStep.model ? [rawStep] : []), modelMap, top);
|
|
3335
|
-
if (recs.length > 0) steps.push({
|
|
3336
|
-
step: rawStep.step ?? "",
|
|
3337
|
-
recommendations: recs
|
|
3338
|
-
});
|
|
3339
|
-
}
|
|
3340
|
-
validatePipelineCompatibility(steps, modelMap);
|
|
3341
|
-
return {
|
|
3342
|
-
type: Complexities.Pipeline,
|
|
3343
|
-
summary: parsed.summary ?? "",
|
|
3344
|
-
steps
|
|
3345
|
-
};
|
|
3346
|
-
}
|
|
3347
|
-
const recommendations = buildRecommendations(parsed.recommendations ?? parsed ?? [], modelMap, top);
|
|
3348
|
-
return {
|
|
3349
|
-
type: Complexities.Single,
|
|
3350
|
-
recommendations
|
|
3351
|
-
};
|
|
3352
|
-
}
|
|
3353
|
-
//#endregion
|
|
3354
|
-
export { BAILIAN_HOST, BailianError, Budgets, CHANNEL, CONSOLE_GATEWAY_NO_TOKEN_MESSAGE, Capabilities, Complexities, ContextNeeds, DOCS_HOSTS, ExitCode, Features, GLOBAL_OPTIONS, McpClient, Modalities, ModelCategories, QualityPreferences, REGIONS, SOURCE_CONFIG, TAGS, analyzeIntent, appCompletionEndpoint, bailianMcpUrl, buildDocLink, callConsoleGateway, chatEndpoint, clearApiKey, createTrackingEvent, defineCommand, detectOutputFormat, effectiveConsoleGatewayConfig, ensureConfigDir, fetchModelList, flushTelemetry, formatErrorJson, formatJson, formatOutput, formatText, generateFilename, generateToolSchema, getConfigDir, getConfigPath, getCredentialsPath, getModels, imageEndpoint, imageSyncEndpoint, isCI, isInteractive, isLocalFile, isSemanticAvailable, knowledgeRetrieveEndpoint, loadApiKeyFromConfig, loadConfig, localSink, mapApiError, maskToken, mcpWebSearchEndpoint, memoryAddEndpoint, memoryListEndpoint, memoryNodeEndpoint, memorySearchEndpoint, parseBooleanValue, parseConfigFile, parseOptionalBooleanValue, parseSSE, profileSchemaEndpoint, rankModels, readConfigFile, recallCandidates, recallSemantic, remoteSink, request, requestJson, resolveBooleanFlag, resolveConsoleGatewayCredential, resolveCredential, resolveFileUrl, resolveOutputDir, resolveWatermark, saveApiKeyToConfig, signRequest, speechRecognizeEndpoint, speechSynthesizeEndpoint, stripUndefined, taskEndpoint, trackCommandExecution, trackingHeaders, uploadFile, userProfileEndpoint, videoGenerateEndpoint, writeConfigFile };
|
|
183
|
+
{"type":"single","recommendations":[{"model":"model ID","reason":"alternative analysis","highlights":["differentiators"]}]}`;else if(c===`scoped`){let e=n.modelPreference?.targets?.length?`\n\n## Scope Restriction\nThe user explicitly requested recommendations from: ${n.modelPreference.targets.join(`, `)}. Prioritize models within this scope.`:``;l=(n.complexity===q.Pipeline?Sr:xr)+e}else l=n.complexity===q.Pipeline?Sr:xr;let u=a?.enableThinking??!1,d=n.complexity===q.Pipeline?`Intent Analysis:\n${s}\n\nCandidate Models:\n${o}\n\nUser Request: ${r}\n\nRecommend up to ${i} models for each pipeline step. Respond in English only.`:`Intent Analysis:\n${s}\n\nCandidate Models:\n${o}\n\nUser Request: ${r}\n\nRecommend up to ${i} models. Respond in English only.`,f={model:u?`qwen3.6-flash`:`qwen-flash`,messages:[{role:`system`,content:l},{role:`user`,content:d}],max_tokens:4096,temperature:0};u&&(f.stream=!0,f.enable_thinking=!0);let p=Me(e.baseUrl),m;if(u){let t=await ht(e,{url:p,method:`POST`,body:f,stream:!0}),n=``,r=!1;for await(let e of yt(t)){if(e.data===`[DONE]`)break;try{let t=JSON.parse(e.data);for(let e of t.choices){let t=e.delta;t.reasoning_content&&a?.onThinking&&a.onThinking(t.reasoning_content),t.content&&(r||(r=!0,a?.onContentStart?.()),n+=t.content)}}catch{}}m=n||`{}`}else m=(await B(e,{url:p,method:`POST`,body:f})).choices?.[0]?.message?.content??`{}`;let h;try{let e=m.match(/\{[\s\S]*\}/);h=JSON.parse(e?.[0]??`{}`)}catch{return{type:q.Single,recommendations:[]}}let g=new Map(t.map(({model:e})=>[e.model,e]));if(h.type===q.Pipeline&&Array.isArray(h.steps)){let e=[];for(let t of h.steps){let n=mi(t.recommendations??(t.model?[t]:[]),g,i);n.length>0&&e.push({step:t.step??``,recommendations:n})}return hi(e,g),{type:q.Pipeline,summary:h.summary??``,steps:e}}let _=mi(h.recommendations??h??[],g,i);return{type:q.Single,recommendations:_}}export{le as BAILIAN_HOST,N as BailianError,vr as Budgets,ut as CHANNEL,De as CONSOLE_GATEWAY_NO_TOKEN_MESSAGE,X as Capabilities,q as Complexities,J as ContextNeeds,mn as DEFAULT_TRAINING_TYPE,ce as DOCS_HOSTS,M as ExitCode,yr as Features,jn as GLOBAL_OPTIONS,xn as INSUFFICIENT_SAMPLES_CODE,Lt as MAX_DATASET_BYTES,vt as McpClient,_r as Modalities,br as ModelCategories,Y as QualityPreferences,F as REGIONS,ft as SOURCE_CONFIG,dt as TAGS,pn as TRAINING_TYPES_CLI,U as TRAINING_TYPE_MAP,Cr as analyzeIntent,Le as appCompletionEndpoint,_t as bailianMcpUrl,pi as buildDocLink,wt as callConsoleGateway,cn as cancelFineTune,Me as chatEndpoint,Te as clearApiKey,Cn as createDeployment,an as createFineTune,Un as createTrackingEvent,An as defineCommand,It as deleteDataset,En as deleteDeployment,ln as deleteFineTune,ve as detectOutputFormat,St as effectiveConsoleGatewayConfig,R as ensureConfigDir,fn as exportCheckpoint,bn as fetchModelCapability,Tt as fetchModelList,$n as flushTelemetry,_e as formatErrorJson,rn as formatIssue,ge as formatJson,ye as formatOutput,he as formatText,Nn as generateFilename,I as getConfigDir,L as getConfigPath,me as getCredentialsPath,Ft as getDataset,Tn as getDeployment,sn as getFineTune,un as getFineTuneLogs,gr as getModels,Ne as imageEndpoint,Pe as imageSyncEndpoint,Ln as isCI,In as isInteractive,At as isLocalFile,ei as isSemanticAvailable,hn as isTrainingTypeCli,Je as knowledgeChatEndpoint,Ke as knowledgeRetrieveEndpoint,qe as knowledgeSearchEndpoint,dn as listCheckpoints,Pt as listDatasets,Dn as listDeployableModels,wn as listDeployments,on as listFineTunes,nn as listSupportedFormats,yn as listSupportedTrainingTypes,Ce as loadApiKeyFromConfig,Se as loadConfig,er as localSink,P as mapApiError,pt as maskToken,Ye as mcpWebSearchEndpoint,Re as memoryAddEndpoint,Be as memoryListEndpoint,Ve as memoryNodeEndpoint,ze as memorySearchEndpoint,vn as modelSupportsTrainingType,zn as parseBooleanValue,pe as parseConfigFile,zt as parseDatasetSchemaFlag,Bn as parseOptionalBooleanValue,yt as parseSSE,$t as pickValidator,Sn as preflightBatchSizeGate,We as profileSchemaEndpoint,gi as rankModels,be as readConfigFile,Rr as recallCandidates,ci as recallSemantic,en as registerValidator,tr as remoteSink,ht as request,B as requestJson,Vn as resolveBooleanFlag,Oe as resolveConsoleGatewayCredential,Ee as resolveCredential,jt as resolveFileUrl,Fn as resolveOutputDir,Hn as resolveWatermark,we as saveApiKeyToConfig,On as scaleDeployment,ke as signRequest,Ue as speechRecognizeEndpoint,He as speechSynthesizeEndpoint,Rn as stripUndefined,Ie as taskEndpoint,gn as toServerTrainingType,ar as trackCommandExecution,z as trackingHeaders,_n as trainingTypeMethodVariant,kn as updateDeployment,Nt as uploadDataset,kt as uploadFile,Ge as userProfileEndpoint,tn as validateDataset,Fe as videoGenerateEndpoint,xe as writeConfigFile};
|