@zqagent/core 0.2.16 → 0.2.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.oss.en.md +13 -0
- package/README.oss.md +11 -0
- package/README.oss.zh-TW.md +11 -0
- package/dist/cli/index.cjs +764 -53
- package/dist/cli/index.cjs.map +1 -1
- package/dist/cli/index.js +764 -53
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +16 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/server/index.cjs +733 -47
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +739 -53
- package/dist/server/index.js.map +1 -1
- package/dist/tools/explore.cjs.map +1 -1
- package/dist/tools/explore.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.cjs
CHANGED
|
@@ -588,7 +588,7 @@ var import_config = require("dotenv/config");
|
|
|
588
588
|
var fs34 = __toESM(require("fs"), 1);
|
|
589
589
|
var readline4 = __toESM(require("readline"), 1);
|
|
590
590
|
var path43 = __toESM(require("path"), 1);
|
|
591
|
-
var
|
|
591
|
+
var import_child_process2 = require("child_process");
|
|
592
592
|
var import_util = require("util");
|
|
593
593
|
|
|
594
594
|
// src/index.ts
|
|
@@ -747,15 +747,27 @@ function networkErrorHints(message, errorType = "") {
|
|
|
747
747
|
hints.push("\u2464 IPv6 \u6296\u52A8\u53EF\u8BD5\uFF1ANODE_OPTIONS=--dns-result-order=ipv4first");
|
|
748
748
|
return hints;
|
|
749
749
|
}
|
|
750
|
+
function authErrorHints(message, code = "") {
|
|
751
|
+
const text = `${message} ${code}`;
|
|
752
|
+
if (!/401|403|unauthorized|forbidden|invalid[_\s]*api[_\s]*key|api[\s_-]*key\s*(?:无效|invalid)|管理令牌无效/i.test(text)) {
|
|
753
|
+
return [];
|
|
754
|
+
}
|
|
755
|
+
return [
|
|
756
|
+
"\u51ED\u636E\u65E0\u6548\uFF1A\u82E5\u7528\u7684\u662F\u300C\u5FD7\u524D\u5927\u6A21\u578B\uFF08\u5185\u7F6E\uFF09\u300D\uFF0C\u5728\u8282\u70B9\u8BBE\u7F6E\u7684\u6A21\u578B\u9875\u70B9\u300C\u5237\u65B0\u5185\u7F6E\u6A21\u578B\u300D\u91CD\u65B0\u9886\u53D6 Key\uFF08\u5728\u63A7\u5236\u53F0\u91CD\u7F6E\u8FC7 Key \u540E\u9700\u8981\u8FD9\u4E00\u6B65\uFF09\uFF1B\u82E5\u662F\u81EA\u586B\u7684\u4F9B\u5E94\u5546\uFF0C\u8BF7\u68C0\u67E5 Key \u662F\u5426\u6B63\u786E\u6216\u5DF2\u8FC7\u671F"
|
|
757
|
+
];
|
|
758
|
+
}
|
|
750
759
|
function paramErrorHints(message, code = "") {
|
|
751
760
|
const text = `${message} ${code}`;
|
|
752
761
|
const hints = [];
|
|
753
|
-
if (/not[_\s]*(activated|enabled|purchased)|arrearage|quota|subscription|insufficient
|
|
762
|
+
if (/not[_\s]*(activated|enabled|purchased)|arrearage|quota|subscription|insufficient|未开通|欠费|额度|余额不足/i.test(
|
|
754
763
|
text
|
|
755
764
|
)) {
|
|
756
765
|
hints.push(
|
|
757
766
|
"\u8BE5\u6A21\u578B\u5728\u6B64 **API Key/\u8D26\u53F7** \u4E0B\u672A\u5F00\u901A\uFF08\u6216\u8D26\u53F7\u6B20\u8D39\u3001\u989D\u5EA6\u7528\u5C3D\uFF09\uFF1A\u5230\u7F51\u5173\u63A7\u5236\u53F0\u5F00\u901A\u8BE5\u6A21\u578B\uFF0C\u6216\u6362\u4E00\u4E2A\u5DF2\u5F00\u901A\u7684\u6A21\u578B"
|
|
758
767
|
);
|
|
768
|
+
hints.push(
|
|
769
|
+
"\u5982\u679C\u4F60\u7528\u7684\u662F\u300C\u5FD7\u524D\u5927\u6A21\u578B\uFF08\u5185\u7F6E\uFF09\u300D\uFF1A\u5230 https://hub.cd-zq.com \u67E5\u770B\u4F59\u989D\u5E76\u5145\u503C\uFF1B\u4E5F\u53EF\u4EE5\u5148\u5207\u6362\u5230\u4F60\u81EA\u5DF1\u914D\u7F6E\u7684\u5176\u5B83\u6A21\u578B\u7EE7\u7EED\uFF08\u8282\u70B9\u8BBE\u7F6E \u2192 \u6A21\u578B \u2192 \u8BBE\u4E3A\u9ED8\u8BA4\uFF09"
|
|
770
|
+
);
|
|
759
771
|
}
|
|
760
772
|
if (/invalid[_\s]*parameter|invalidparameter|required[_\s]+parameter|missing[_\s]+parameter|invalid[_\s]*model|model[_\s]*not[_\s]*found|not[_\s]*support|unsupported/i.test(
|
|
761
773
|
text
|
|
@@ -4998,6 +5010,9 @@ var ConsoleHook = class {
|
|
|
4998
5010
|
for (const hint of networkErrorHints(error2, errorType)) {
|
|
4999
5011
|
cliLog(` \u{1F4A1} ${hint}`);
|
|
5000
5012
|
}
|
|
5013
|
+
for (const hint of authErrorHints(error2, errorType)) {
|
|
5014
|
+
cliLog(` \u{1F4A1} ${hint}`);
|
|
5015
|
+
}
|
|
5001
5016
|
for (const hint of paramErrorHints(error2)) {
|
|
5002
5017
|
cliLog(` \u{1F4A1} ${hint}`);
|
|
5003
5018
|
}
|
|
@@ -9991,6 +10006,15 @@ function commonLegacyFiles() {
|
|
|
9991
10006
|
return [path17.join(stateDir(), "data", "node-llm.json")];
|
|
9992
10007
|
}
|
|
9993
10008
|
|
|
10009
|
+
// src/server/llmIds.ts
|
|
10010
|
+
init_cjs_shims();
|
|
10011
|
+
var GLOBAL_PROVIDER_ID = "__env__";
|
|
10012
|
+
var BUILTIN_PROVIDER_ID = "__zqai__";
|
|
10013
|
+
function isBuiltinProvider(id) {
|
|
10014
|
+
return id === BUILTIN_PROVIDER_ID;
|
|
10015
|
+
}
|
|
10016
|
+
var FALLBACK_MODEL = "gpt-4o";
|
|
10017
|
+
|
|
9994
10018
|
// src/cli/connection.ts
|
|
9995
10019
|
var PROVIDERS = Object.fromEntries(
|
|
9996
10020
|
LLM_PRESETS.map((p) => [
|
|
@@ -10105,6 +10129,7 @@ function useConnection(id) {
|
|
|
10105
10129
|
return true;
|
|
10106
10130
|
}
|
|
10107
10131
|
function removeConnection(id) {
|
|
10132
|
+
if (id === BUILTIN_PROVIDER_ID) return false;
|
|
10108
10133
|
const f = read();
|
|
10109
10134
|
const next = f.providers.filter((p) => p.id !== id);
|
|
10110
10135
|
if (next.length === f.providers.length) return false;
|
|
@@ -10388,7 +10413,7 @@ var GLYPHS = {
|
|
|
10388
10413
|
T: ["\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " \u2588\u2588 ", " "]
|
|
10389
10414
|
};
|
|
10390
10415
|
var GLYPH_ROWS = 6;
|
|
10391
|
-
var GLYPH_COLS =
|
|
10416
|
+
var GLYPH_COLS = 11;
|
|
10392
10417
|
var GRADIENT = [
|
|
10393
10418
|
[34, 211, 238],
|
|
10394
10419
|
[99, 102, 241],
|
|
@@ -10994,7 +11019,23 @@ var Store = class {
|
|
|
10994
11019
|
legacyFiles: [path19.join(this.root, "node-llm.json")]
|
|
10995
11020
|
});
|
|
10996
11021
|
const old = new Map(cur.providers.map((p) => [p.id, p]));
|
|
10997
|
-
const
|
|
11022
|
+
const src = [...cfg.providers];
|
|
11023
|
+
const prevBuiltin = cur.providers.find((p) => p.id === BUILTIN_PROVIDER_ID);
|
|
11024
|
+
if (prevBuiltin && !src.some((p) => p.id === BUILTIN_PROVIDER_ID)) {
|
|
11025
|
+
src.unshift({
|
|
11026
|
+
id: prevBuiltin.id,
|
|
11027
|
+
name: prevBuiltin.name,
|
|
11028
|
+
type: prevBuiltin.type,
|
|
11029
|
+
baseURL: prevBuiltin.baseURL,
|
|
11030
|
+
model: prevBuiltin.model,
|
|
11031
|
+
apiKey: decryptKey(prevBuiltin.apiKeyEnc, file) ?? void 0,
|
|
11032
|
+
reasoningEffort: prevBuiltin.reasoningEffort ?? null,
|
|
11033
|
+
...prevBuiltin.models ? { models: prevBuiltin.models } : {},
|
|
11034
|
+
...prevBuiltin.nonChat ? { nonChat: prevBuiltin.nonChat } : {},
|
|
11035
|
+
...prevBuiltin.modelMeta ? { modelMeta: prevBuiltin.modelMeta } : {}
|
|
11036
|
+
});
|
|
11037
|
+
}
|
|
11038
|
+
const providers = src.map((p) => {
|
|
10998
11039
|
const prev = old.get(p.id);
|
|
10999
11040
|
const apiKeyEnc = p.apiKey ? encryptKey(p.apiKey, file) : prev?.apiKeyEnc ?? "";
|
|
11000
11041
|
return {
|
|
@@ -11185,7 +11226,6 @@ function loadServerMcpConfigs(tenant) {
|
|
|
11185
11226
|
|
|
11186
11227
|
// src/server/nodeLlm.ts
|
|
11187
11228
|
init_cjs_shims();
|
|
11188
|
-
var GLOBAL_PROVIDER_ID = "__env__";
|
|
11189
11229
|
function envProvider() {
|
|
11190
11230
|
const apiKey = process.env.OPENAI_API_KEY;
|
|
11191
11231
|
if (!apiKey) return null;
|
|
@@ -11228,19 +11268,26 @@ function nodeLlmView(cfg) {
|
|
|
11228
11268
|
global: true
|
|
11229
11269
|
}
|
|
11230
11270
|
] : [],
|
|
11231
|
-
...cfg.providers.map((p) =>
|
|
11232
|
-
|
|
11233
|
-
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
|
|
11240
|
-
|
|
11241
|
-
|
|
11242
|
-
|
|
11243
|
-
|
|
11271
|
+
...cfg.providers.map((p) => {
|
|
11272
|
+
const builtin = isBuiltinProvider(p.id);
|
|
11273
|
+
return {
|
|
11274
|
+
id: p.id,
|
|
11275
|
+
name: p.name,
|
|
11276
|
+
type: p.type ?? "",
|
|
11277
|
+
baseURL: p.baseURL,
|
|
11278
|
+
model: p.model,
|
|
11279
|
+
hasApiKey: Boolean(p.apiKey),
|
|
11280
|
+
models: p.models ?? [],
|
|
11281
|
+
nonChat: p.nonChat ?? [],
|
|
11282
|
+
modelMeta: p.modelMeta ?? [],
|
|
11283
|
+
reasoningEffort: p.reasoningEffort ?? null,
|
|
11284
|
+
global: false,
|
|
11285
|
+
/** 平台内置(接入 Hub 后自动下发,用户不用关心 Key) */
|
|
11286
|
+
builtin,
|
|
11287
|
+
/** 不可编辑的字段:控制台据此把 baseURL / key 显示为只读 */
|
|
11288
|
+
...builtin ? { locked: ["baseURL", "apiKey"] } : {}
|
|
11289
|
+
};
|
|
11290
|
+
})
|
|
11244
11291
|
];
|
|
11245
11292
|
return {
|
|
11246
11293
|
defaultProviderId: cfg.defaultProviderId ?? null,
|
|
@@ -11253,27 +11300,42 @@ function applyNodeLlmPatch(cfg, raw) {
|
|
|
11253
11300
|
const next = { providers: cfg.providers, defaultProviderId: cfg.defaultProviderId };
|
|
11254
11301
|
if (Array.isArray(raw?.providers)) {
|
|
11255
11302
|
const old = new Map(cfg.providers.map((p) => [p.id, p]));
|
|
11256
|
-
|
|
11257
|
-
|
|
11258
|
-
|
|
11259
|
-
|
|
11260
|
-
|
|
11261
|
-
|
|
11262
|
-
|
|
11263
|
-
|
|
11264
|
-
|
|
11265
|
-
|
|
11266
|
-
|
|
11267
|
-
|
|
11268
|
-
|
|
11269
|
-
|
|
11270
|
-
|
|
11271
|
-
|
|
11272
|
-
|
|
11273
|
-
|
|
11274
|
-
|
|
11275
|
-
|
|
11276
|
-
|
|
11303
|
+
const incoming = raw.providers.filter((x) => Boolean(x) && typeof x === "object").filter((x) => x.global !== true && String(x.id ?? "") !== GLOBAL_PROVIDER_ID);
|
|
11304
|
+
const prevBuiltin = cfg.providers.find((p) => isBuiltinProvider(p.id));
|
|
11305
|
+
const builtinPatch = incoming.find((x) => isBuiltinProvider(String(x.id ?? "")));
|
|
11306
|
+
const keptBuiltin = prevBuiltin ? [
|
|
11307
|
+
{
|
|
11308
|
+
...prevBuiltin,
|
|
11309
|
+
...builtinPatch?.model != null ? { model: String(builtinPatch.model).trim() || prevBuiltin.model } : {},
|
|
11310
|
+
...normalizeModelList(builtinPatch?.models) ? { models: normalizeModelList(builtinPatch?.models) } : {},
|
|
11311
|
+
...builtinPatch?.reasoningEffort !== void 0 ? { reasoningEffort: normReasoningEffort(builtinPatch.reasoningEffort) } : {},
|
|
11312
|
+
...typeof builtinPatch?.name === "string" && builtinPatch.name.trim() ? { name: builtinPatch.name.trim() } : {}
|
|
11313
|
+
}
|
|
11314
|
+
] : [];
|
|
11315
|
+
next.providers = [
|
|
11316
|
+
...keptBuiltin,
|
|
11317
|
+
...incoming.filter((x) => !isBuiltinProvider(String(x.id ?? ""))).map((x) => {
|
|
11318
|
+
const id = String(x.id ?? "").trim();
|
|
11319
|
+
if (!id) throw new ApiError(400, "bad_request", "\u4F9B\u5E94\u5546 id \u4E0D\u80FD\u4E3A\u7A7A");
|
|
11320
|
+
const prev = old.get(id);
|
|
11321
|
+
const apiKey = String(x.apiKey ?? "").trim();
|
|
11322
|
+
const models = normalizeModelList(x.models) ?? prev?.models;
|
|
11323
|
+
const nonChat = normalizeModelList(x.nonChat) ?? prev?.nonChat;
|
|
11324
|
+
const modelMeta = normalizeModelMeta(x.modelMeta) ?? prev?.modelMeta;
|
|
11325
|
+
return {
|
|
11326
|
+
id,
|
|
11327
|
+
name: String(x.name ?? prev?.name ?? id).trim(),
|
|
11328
|
+
type: x.type == null ? prev?.type : String(x.type),
|
|
11329
|
+
baseURL: String(x.baseURL ?? prev?.baseURL ?? "").trim(),
|
|
11330
|
+
model: String(x.model ?? prev?.model ?? "").trim(),
|
|
11331
|
+
apiKey: apiKey || prev?.apiKey,
|
|
11332
|
+
reasoningEffort: x.reasoningEffort === void 0 ? prev?.reasoningEffort ?? null : normReasoningEffort(x.reasoningEffort),
|
|
11333
|
+
...models ? { models } : {},
|
|
11334
|
+
...nonChat ? { nonChat } : {},
|
|
11335
|
+
...modelMeta ? { modelMeta } : {}
|
|
11336
|
+
};
|
|
11337
|
+
})
|
|
11338
|
+
];
|
|
11277
11339
|
}
|
|
11278
11340
|
if (typeof raw?.defaultProviderId === "string") {
|
|
11279
11341
|
const id = raw.defaultProviderId.trim();
|
|
@@ -11293,6 +11355,9 @@ function nodeDefaultProvider(store) {
|
|
|
11293
11355
|
if (cfg.providers.length === 0) return null;
|
|
11294
11356
|
return cfg.providers.find((p) => p.id === cfg.defaultProviderId) ?? cfg.providers[0] ?? null;
|
|
11295
11357
|
}
|
|
11358
|
+
function defaultTenantModel(store) {
|
|
11359
|
+
return process.env.OPENAI_MODEL || process.env.MODEL || nodeDefaultProvider(store)?.model || FALLBACK_MODEL;
|
|
11360
|
+
}
|
|
11296
11361
|
function resolveSessionProvider(store, tenant, providerId) {
|
|
11297
11362
|
const own = tenant.provider ?? {};
|
|
11298
11363
|
if (providerId) {
|
|
@@ -11322,6 +11387,208 @@ function resolveSessionProvider(store, tenant, providerId) {
|
|
|
11322
11387
|
return { ...own, model: tenant.model };
|
|
11323
11388
|
}
|
|
11324
11389
|
|
|
11390
|
+
// src/server/builtinLlm.ts
|
|
11391
|
+
init_cjs_shims();
|
|
11392
|
+
var FETCH_TIMEOUT_MS = 8e3;
|
|
11393
|
+
var RETRY_AFTER_MS = 5 * 6e4;
|
|
11394
|
+
function hubBase(cred) {
|
|
11395
|
+
return (cred.hubUrl ?? "").replace(/\/+$/, "");
|
|
11396
|
+
}
|
|
11397
|
+
function asProvider(grant) {
|
|
11398
|
+
const baseURL = String(grant.baseURL ?? "").trim();
|
|
11399
|
+
const apiKey = String(grant.apiKey ?? "").trim();
|
|
11400
|
+
const model = String(grant.model ?? "").trim();
|
|
11401
|
+
if (!baseURL || !apiKey) return null;
|
|
11402
|
+
return {
|
|
11403
|
+
id: BUILTIN_PROVIDER_ID,
|
|
11404
|
+
name: String(grant.name ?? "").trim() || "\u5FD7\u524D\u5927\u6A21\u578B\uFF08\u5185\u7F6E\uFF09",
|
|
11405
|
+
type: "builtin",
|
|
11406
|
+
baseURL,
|
|
11407
|
+
model,
|
|
11408
|
+
apiKey
|
|
11409
|
+
};
|
|
11410
|
+
}
|
|
11411
|
+
async function enrichModels(p) {
|
|
11412
|
+
try {
|
|
11413
|
+
const r = await Promise.race([
|
|
11414
|
+
fetchModels(p.baseURL, p.apiKey ?? "", p.model),
|
|
11415
|
+
new Promise((resolve25) => {
|
|
11416
|
+
const t = setTimeout(() => resolve25(null), FETCH_TIMEOUT_MS);
|
|
11417
|
+
t.unref?.();
|
|
11418
|
+
})
|
|
11419
|
+
]);
|
|
11420
|
+
if (!r?.models?.length) return p;
|
|
11421
|
+
return {
|
|
11422
|
+
...p,
|
|
11423
|
+
// 控制面没给默认型号时,取供应商返回的第一个,避免模型为空让用户卡住
|
|
11424
|
+
model: p.model || r.models[0],
|
|
11425
|
+
models: r.models,
|
|
11426
|
+
...r.nonChat?.length ? { nonChat: r.nonChat } : {},
|
|
11427
|
+
...r.modelMeta?.length ? { modelMeta: r.modelMeta } : {}
|
|
11428
|
+
};
|
|
11429
|
+
} catch {
|
|
11430
|
+
return p;
|
|
11431
|
+
}
|
|
11432
|
+
}
|
|
11433
|
+
function saveBuiltin(store, provider) {
|
|
11434
|
+
const cfg = store.loadNodeLlm();
|
|
11435
|
+
const others = cfg.providers.filter((p) => p.id !== BUILTIN_PROVIDER_ID);
|
|
11436
|
+
const prev = cfg.providers.find((p) => p.id === BUILTIN_PROVIDER_ID);
|
|
11437
|
+
const merged = {
|
|
11438
|
+
...provider,
|
|
11439
|
+
// 用户选过的型号/候选列表/推理强度/显示名都保留;只有托管字段(baseURL/key)强制以控制面为准
|
|
11440
|
+
...prev?.model ? { model: prev.model } : {},
|
|
11441
|
+
...prev?.models?.length ? { models: prev.models } : {},
|
|
11442
|
+
...prev?.reasoningEffort != null ? { reasoningEffort: prev.reasoningEffort } : {},
|
|
11443
|
+
...prev?.name ? { name: prev.name } : {}
|
|
11444
|
+
};
|
|
11445
|
+
store.saveNodeLlm({
|
|
11446
|
+
providers: [merged, ...others],
|
|
11447
|
+
// 之前没有默认且用户也没指定时,让内置模型成为默认——「开箱即用」
|
|
11448
|
+
defaultProviderId: cfg.defaultProviderId ?? BUILTIN_PROVIDER_ID
|
|
11449
|
+
});
|
|
11450
|
+
adoptBuiltinModelForTenants(store, merged.model);
|
|
11451
|
+
}
|
|
11452
|
+
var LEGACY_DEFAULT_MODELS = /* @__PURE__ */ new Set([FALLBACK_MODEL, "deepseek-v4-flash"]);
|
|
11453
|
+
function adoptBuiltinModelForTenants(store, model) {
|
|
11454
|
+
if (!model) return;
|
|
11455
|
+
for (const id of store.listTenants()) {
|
|
11456
|
+
const tenant = store.loadTenant(id);
|
|
11457
|
+
if (!tenant || !LEGACY_DEFAULT_MODELS.has(tenant.model)) continue;
|
|
11458
|
+
if (tenant.provider?.apiKey) continue;
|
|
11459
|
+
tenant.model = model;
|
|
11460
|
+
store.saveTenant(tenant);
|
|
11461
|
+
}
|
|
11462
|
+
}
|
|
11463
|
+
async function ensureBuiltinProvider(store, opts = {}) {
|
|
11464
|
+
const cred = store.loadFleetCredential();
|
|
11465
|
+
if (!cred?.fleetToken || !cred.fleetSecret) {
|
|
11466
|
+
return { status: "disabled", reason: "\u8282\u70B9\u672A\u63A5\u5165 Hub" };
|
|
11467
|
+
}
|
|
11468
|
+
const hub = hubBase(cred);
|
|
11469
|
+
if (!hub) return { status: "disabled", reason: "\u7F3A\u5C11 Hub \u5730\u5740" };
|
|
11470
|
+
const local = store.loadNodeLlm().providers.find((p) => p.id === BUILTIN_PROVIDER_ID);
|
|
11471
|
+
if (local && !opts.force) {
|
|
11472
|
+
adoptBuiltinModelForTenants(store, local.model);
|
|
11473
|
+
return { status: "ready", provider: local, refreshed: false };
|
|
11474
|
+
}
|
|
11475
|
+
const cached3 = cred.builtinLlm ? asProvider(cred.builtinLlm) : null;
|
|
11476
|
+
let res;
|
|
11477
|
+
try {
|
|
11478
|
+
res = await fetch(`${hub}/api/hub/node/builtin-llm`, {
|
|
11479
|
+
headers: {
|
|
11480
|
+
Authorization: `Bearer ${cred.fleetToken}`,
|
|
11481
|
+
"X-Fleet-Secret": cred.fleetSecret,
|
|
11482
|
+
"X-Node-Id": cred.nodeId
|
|
11483
|
+
},
|
|
11484
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
11485
|
+
});
|
|
11486
|
+
} catch (e) {
|
|
11487
|
+
if (cached3) {
|
|
11488
|
+
const provider2 = await enrichModels(cached3);
|
|
11489
|
+
saveBuiltin(store, provider2);
|
|
11490
|
+
return { status: "ready", provider: provider2, refreshed: true };
|
|
11491
|
+
}
|
|
11492
|
+
return { status: "error", reason: `\u8FDE\u63A5 Hub \u5931\u8D25\uFF1A${e.message}` };
|
|
11493
|
+
}
|
|
11494
|
+
let body = null;
|
|
11495
|
+
try {
|
|
11496
|
+
body = await res.json();
|
|
11497
|
+
} catch {
|
|
11498
|
+
}
|
|
11499
|
+
if (!res.ok) {
|
|
11500
|
+
const msg = body?.error?.message ?? `HTTP ${res.status}`;
|
|
11501
|
+
if (res.status === 401 || res.status === 403) {
|
|
11502
|
+
return { status: "unavailable", reason: msg };
|
|
11503
|
+
}
|
|
11504
|
+
if (cached3) {
|
|
11505
|
+
const provider2 = await enrichModels(cached3);
|
|
11506
|
+
saveBuiltin(store, provider2);
|
|
11507
|
+
return { status: "ready", provider: provider2, refreshed: true };
|
|
11508
|
+
}
|
|
11509
|
+
return { status: "error", reason: msg };
|
|
11510
|
+
}
|
|
11511
|
+
const grant = body?.data?.builtinLlm;
|
|
11512
|
+
if (!grant) {
|
|
11513
|
+
const why = String(body?.data?.reason ?? "").trim();
|
|
11514
|
+
return { status: "unavailable", reason: why || "\u63A7\u5236\u9762\u672A\u4E0B\u53D1\u5185\u7F6E\u6A21\u578B" };
|
|
11515
|
+
}
|
|
11516
|
+
const parsed = asProvider(grant);
|
|
11517
|
+
if (!parsed) return { status: "unavailable", reason: "\u5185\u7F6E\u6A21\u578B\u914D\u7F6E\u4E0D\u5B8C\u6574" };
|
|
11518
|
+
const provider = await enrichModels(parsed);
|
|
11519
|
+
saveBuiltin(store, provider);
|
|
11520
|
+
return { status: "ready", provider, refreshed: true };
|
|
11521
|
+
}
|
|
11522
|
+
async function fetchLlmBalance(store) {
|
|
11523
|
+
const cred = store.loadFleetCredential();
|
|
11524
|
+
const hub = cred ? hubBase(cred) : "";
|
|
11525
|
+
if (!cred?.fleetToken || !cred.fleetSecret || !hub) {
|
|
11526
|
+
return { available: null, currency: "CNY", reason: "\u8282\u70B9\u672A\u63A5\u5165 Hub" };
|
|
11527
|
+
}
|
|
11528
|
+
try {
|
|
11529
|
+
const res = await fetch(`${hub}/api/hub/node/balance`, {
|
|
11530
|
+
headers: {
|
|
11531
|
+
Authorization: `Bearer ${cred.fleetToken}`,
|
|
11532
|
+
"X-Fleet-Secret": cred.fleetSecret,
|
|
11533
|
+
"X-Node-Id": cred.nodeId
|
|
11534
|
+
},
|
|
11535
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
11536
|
+
});
|
|
11537
|
+
const body = await res.json().catch(() => null);
|
|
11538
|
+
if (!res.ok) {
|
|
11539
|
+
return {
|
|
11540
|
+
available: null,
|
|
11541
|
+
currency: "CNY",
|
|
11542
|
+
reason: body?.data ? "" : `HTTP ${res.status}`
|
|
11543
|
+
};
|
|
11544
|
+
}
|
|
11545
|
+
const d = body?.data ?? {};
|
|
11546
|
+
const available = typeof d.available === "number" ? d.available : null;
|
|
11547
|
+
return {
|
|
11548
|
+
available,
|
|
11549
|
+
currency: typeof d.currency === "string" && d.currency ? d.currency : "CNY",
|
|
11550
|
+
...typeof d.reserved === "number" ? { reserved: d.reserved } : {},
|
|
11551
|
+
// Hub 没配 HUB_PUBLIC_URL 时退回用接入时的 hubUrl
|
|
11552
|
+
topupUrl: typeof d.topupUrl === "string" && d.topupUrl ? d.topupUrl : `${hub}/topup`,
|
|
11553
|
+
...available === null && typeof d.reason === "string" ? { reason: d.reason } : {}
|
|
11554
|
+
};
|
|
11555
|
+
} catch (e) {
|
|
11556
|
+
return {
|
|
11557
|
+
available: null,
|
|
11558
|
+
currency: "CNY",
|
|
11559
|
+
reason: `\u8FDE\u63A5 Hub \u5931\u8D25\uFF1A${e.message}`
|
|
11560
|
+
};
|
|
11561
|
+
}
|
|
11562
|
+
}
|
|
11563
|
+
var AUTH_RETRY_THROTTLE_MS = 6e4;
|
|
11564
|
+
var lastAuthRetryAt = 0;
|
|
11565
|
+
function healBuiltinOnAuthFailure(store, message) {
|
|
11566
|
+
if (!/401|unauthorized|invalid[_\s]*api[_\s]*key|api[\s_-]*key\s*(?:无效|invalid)/i.test(message)) return;
|
|
11567
|
+
if (!store.loadFleetCredential()) return;
|
|
11568
|
+
if (!store.loadNodeLlm().providers.some((p) => p.id === BUILTIN_PROVIDER_ID)) return;
|
|
11569
|
+
if (Date.now() - lastAuthRetryAt < AUTH_RETRY_THROTTLE_MS) return;
|
|
11570
|
+
lastAuthRetryAt = Date.now();
|
|
11571
|
+
void ensureBuiltinProvider(store, { force: true }).catch(() => {
|
|
11572
|
+
});
|
|
11573
|
+
}
|
|
11574
|
+
var lastFailureAt = 0;
|
|
11575
|
+
function scheduleBuiltinProvider(store, log = () => {
|
|
11576
|
+
}) {
|
|
11577
|
+
if (Date.now() - lastFailureAt < RETRY_AFTER_MS) return;
|
|
11578
|
+
void ensureBuiltinProvider(store).then((r) => {
|
|
11579
|
+
if (r.status === "ready") {
|
|
11580
|
+
if (r.refreshed) log(`[builtin-llm] \u5DF2\u4E0B\u53D1\u5185\u7F6E\u6A21\u578B\uFF1A${r.provider.name}\uFF08${r.provider.model}\uFF09`);
|
|
11581
|
+
return;
|
|
11582
|
+
}
|
|
11583
|
+
if (r.status === "disabled") return;
|
|
11584
|
+
lastFailureAt = Date.now();
|
|
11585
|
+
if (r.status === "unavailable") log(`[builtin-llm] \u6682\u65E0\u5185\u7F6E\u6A21\u578B\uFF1A${r.reason}`);
|
|
11586
|
+
else log(`[builtin-llm] \u62C9\u53D6\u5185\u7F6E\u6A21\u578B\u5931\u8D25\uFF1A${r.reason}`);
|
|
11587
|
+
}).catch(() => {
|
|
11588
|
+
lastFailureAt = Date.now();
|
|
11589
|
+
});
|
|
11590
|
+
}
|
|
11591
|
+
|
|
11325
11592
|
// src/server/usage.ts
|
|
11326
11593
|
init_cjs_shims();
|
|
11327
11594
|
var fs19 = __toESM(require("fs"), 1);
|
|
@@ -13383,6 +13650,7 @@ data: ${JSON.stringify(entry.data)}
|
|
|
13383
13650
|
this._setStatus(rt, "error");
|
|
13384
13651
|
this._persist(rt);
|
|
13385
13652
|
this._emitNotify(rt, "error", this._turnEndData(rt, event.data, {}));
|
|
13653
|
+
healBuiltinOnAuthFailure(this.store, String(event.data["error"] ?? ""));
|
|
13386
13654
|
break;
|
|
13387
13655
|
case "interrupted" /* INTERRUPTED */:
|
|
13388
13656
|
this._setStatus(rt, "interrupted");
|
|
@@ -13806,7 +14074,6 @@ var ApiError = class extends Error {
|
|
|
13806
14074
|
};
|
|
13807
14075
|
|
|
13808
14076
|
// src/server/projects.ts
|
|
13809
|
-
var DEFAULT_MODEL = () => process.env.OPENAI_MODEL || process.env.MODEL || "gpt-4o";
|
|
13810
14077
|
function toProjectSummary(store, tenant) {
|
|
13811
14078
|
return {
|
|
13812
14079
|
id: tenant.id,
|
|
@@ -13946,7 +14213,7 @@ function createProject(store, input) {
|
|
|
13946
14213
|
id,
|
|
13947
14214
|
name: explicitName || defaultName,
|
|
13948
14215
|
apiKey: generateApiKey(),
|
|
13949
|
-
model: typeof raw.model === "string" && raw.model.trim() ? raw.model.trim() :
|
|
14216
|
+
model: typeof raw.model === "string" && raw.model.trim() ? raw.model.trim() : defaultTenantModel(store),
|
|
13950
14217
|
provider: {
|
|
13951
14218
|
apiKey: typeof raw.providerApiKey === "string" && raw.providerApiKey.trim() ? raw.providerApiKey.trim() : void 0,
|
|
13952
14219
|
baseURL: typeof raw.baseURL === "string" && raw.baseURL.trim() ? raw.baseURL.trim() : void 0
|
|
@@ -13971,7 +14238,7 @@ function buildNodeInfo(store, opts) {
|
|
|
13971
14238
|
nodeId: opts.nodeId ?? ensureNodeId(store),
|
|
13972
14239
|
platform: process.platform,
|
|
13973
14240
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
13974
|
-
version: "0.2.
|
|
14241
|
+
version: "0.2.20",
|
|
13975
14242
|
admin: opts.admin,
|
|
13976
14243
|
projects: opts.projects
|
|
13977
14244
|
};
|
|
@@ -14187,7 +14454,7 @@ var path25 = __toESM(require("path"), 1);
|
|
|
14187
14454
|
var import_node_child_process4 = require("child_process");
|
|
14188
14455
|
var import_node_module3 = require("module");
|
|
14189
14456
|
function currentVersion() {
|
|
14190
|
-
const injected = "0.2.
|
|
14457
|
+
const injected = "0.2.20"?.trim();
|
|
14191
14458
|
if (injected) return injected;
|
|
14192
14459
|
try {
|
|
14193
14460
|
const req2 = (0, import_node_module3.createRequire)(importMetaUrl);
|
|
@@ -15523,10 +15790,133 @@ function makeDirIn(parentInput, name) {
|
|
|
15523
15790
|
init_cjs_shims();
|
|
15524
15791
|
var fs23 = __toESM(require("fs"), 1);
|
|
15525
15792
|
var path30 = __toESM(require("path"), 1);
|
|
15793
|
+
|
|
15794
|
+
// src/server/zipArchive.ts
|
|
15795
|
+
init_cjs_shims();
|
|
15796
|
+
var zlib = __toESM(require("zlib"), 1);
|
|
15797
|
+
var MAX_ZIP_ENTRIES = 2e4;
|
|
15798
|
+
var LOCAL_SIG = 67324752;
|
|
15799
|
+
var CENTRAL_SIG = 33639248;
|
|
15800
|
+
var EOCD_SIG = 101010256;
|
|
15801
|
+
var FLAG_UTF8 = 2048;
|
|
15802
|
+
var METHOD_STORE = 0;
|
|
15803
|
+
var METHOD_DEFLATE = 8;
|
|
15804
|
+
var CRC_TABLE = (() => {
|
|
15805
|
+
const table = new Int32Array(256);
|
|
15806
|
+
for (let n = 0; n < 256; n++) {
|
|
15807
|
+
let c = n;
|
|
15808
|
+
for (let k = 0; k < 8; k++) {
|
|
15809
|
+
c = c & 1 ? 3988292384 ^ c >>> 1 : c >>> 1;
|
|
15810
|
+
}
|
|
15811
|
+
table[n] = c;
|
|
15812
|
+
}
|
|
15813
|
+
return table;
|
|
15814
|
+
})();
|
|
15815
|
+
function crc32(buf) {
|
|
15816
|
+
let c = -1;
|
|
15817
|
+
for (let i = 0; i < buf.length; i++) {
|
|
15818
|
+
c = CRC_TABLE[(c ^ buf[i]) & 255] ^ c >>> 8;
|
|
15819
|
+
}
|
|
15820
|
+
return (c ^ -1) >>> 0;
|
|
15821
|
+
}
|
|
15822
|
+
function dosDateTime(d) {
|
|
15823
|
+
const year = Math.max(1980, d.getFullYear());
|
|
15824
|
+
return {
|
|
15825
|
+
time: d.getHours() << 11 | d.getMinutes() << 5 | d.getSeconds() >> 1,
|
|
15826
|
+
date: year - 1980 << 9 | d.getMonth() + 1 << 5 | d.getDate()
|
|
15827
|
+
};
|
|
15828
|
+
}
|
|
15829
|
+
function buildZip(entries) {
|
|
15830
|
+
if (entries.length > MAX_ZIP_ENTRIES) {
|
|
15831
|
+
throw new Error(`\u5F52\u6863\u6761\u76EE\u8FC7\u591A\uFF08${entries.length} > ${MAX_ZIP_ENTRIES}\uFF09`);
|
|
15832
|
+
}
|
|
15833
|
+
const chunks = [];
|
|
15834
|
+
const central = [];
|
|
15835
|
+
let offset = 0;
|
|
15836
|
+
for (const e of entries) {
|
|
15837
|
+
const name = Buffer.from(e.name, "utf-8");
|
|
15838
|
+
const isDir = e.name.endsWith("/");
|
|
15839
|
+
const raw = isDir ? Buffer.alloc(0) : e.data ?? Buffer.alloc(0);
|
|
15840
|
+
let method = METHOD_STORE;
|
|
15841
|
+
let body = raw;
|
|
15842
|
+
if (!isDir && raw.length > 0) {
|
|
15843
|
+
const deflated = zlib.deflateRawSync(raw, { level: 6 });
|
|
15844
|
+
if (deflated.length < raw.length) {
|
|
15845
|
+
method = METHOD_DEFLATE;
|
|
15846
|
+
body = deflated;
|
|
15847
|
+
}
|
|
15848
|
+
}
|
|
15849
|
+
const crc = isDir ? 0 : crc32(raw);
|
|
15850
|
+
const { time, date } = dosDateTime(e.mtime ?? /* @__PURE__ */ new Date());
|
|
15851
|
+
const local = Buffer.alloc(30);
|
|
15852
|
+
local.writeUInt32LE(LOCAL_SIG, 0);
|
|
15853
|
+
local.writeUInt16LE(20, 4);
|
|
15854
|
+
local.writeUInt16LE(FLAG_UTF8, 6);
|
|
15855
|
+
local.writeUInt16LE(method, 8);
|
|
15856
|
+
local.writeUInt16LE(time, 10);
|
|
15857
|
+
local.writeUInt16LE(date, 12);
|
|
15858
|
+
local.writeUInt32LE(crc, 14);
|
|
15859
|
+
local.writeUInt32LE(body.length, 18);
|
|
15860
|
+
local.writeUInt32LE(raw.length, 22);
|
|
15861
|
+
local.writeUInt16LE(name.length, 26);
|
|
15862
|
+
local.writeUInt16LE(0, 28);
|
|
15863
|
+
chunks.push(local, name);
|
|
15864
|
+
if (body.length > 0) chunks.push(body);
|
|
15865
|
+
central.push({
|
|
15866
|
+
name,
|
|
15867
|
+
method,
|
|
15868
|
+
crc,
|
|
15869
|
+
csize: body.length,
|
|
15870
|
+
usize: raw.length,
|
|
15871
|
+
offset,
|
|
15872
|
+
time,
|
|
15873
|
+
date,
|
|
15874
|
+
isDir
|
|
15875
|
+
});
|
|
15876
|
+
offset += local.length + name.length + body.length;
|
|
15877
|
+
}
|
|
15878
|
+
const cdStart = offset;
|
|
15879
|
+
for (const c of central) {
|
|
15880
|
+
const head = Buffer.alloc(46);
|
|
15881
|
+
head.writeUInt32LE(CENTRAL_SIG, 0);
|
|
15882
|
+
head.writeUInt16LE(20, 4);
|
|
15883
|
+
head.writeUInt16LE(20, 6);
|
|
15884
|
+
head.writeUInt16LE(FLAG_UTF8, 8);
|
|
15885
|
+
head.writeUInt16LE(c.method, 10);
|
|
15886
|
+
head.writeUInt16LE(c.time, 12);
|
|
15887
|
+
head.writeUInt16LE(c.date, 14);
|
|
15888
|
+
head.writeUInt32LE(c.crc, 16);
|
|
15889
|
+
head.writeUInt32LE(c.csize, 20);
|
|
15890
|
+
head.writeUInt32LE(c.usize, 24);
|
|
15891
|
+
head.writeUInt16LE(c.name.length, 28);
|
|
15892
|
+
head.writeUInt16LE(0, 30);
|
|
15893
|
+
head.writeUInt16LE(0, 32);
|
|
15894
|
+
head.writeUInt16LE(0, 34);
|
|
15895
|
+
head.writeUInt16LE(0, 36);
|
|
15896
|
+
head.writeUInt32LE(c.isDir ? 16 : 0, 38);
|
|
15897
|
+
head.writeUInt32LE(c.offset, 42);
|
|
15898
|
+
chunks.push(head, c.name);
|
|
15899
|
+
offset += head.length + c.name.length;
|
|
15900
|
+
}
|
|
15901
|
+
const eocd = Buffer.alloc(22);
|
|
15902
|
+
eocd.writeUInt32LE(EOCD_SIG, 0);
|
|
15903
|
+
eocd.writeUInt16LE(0, 4);
|
|
15904
|
+
eocd.writeUInt16LE(0, 6);
|
|
15905
|
+
eocd.writeUInt16LE(central.length, 8);
|
|
15906
|
+
eocd.writeUInt16LE(central.length, 10);
|
|
15907
|
+
eocd.writeUInt32LE(offset - cdStart, 12);
|
|
15908
|
+
eocd.writeUInt32LE(cdStart, 16);
|
|
15909
|
+
eocd.writeUInt16LE(0, 20);
|
|
15910
|
+
chunks.push(eocd);
|
|
15911
|
+
return Buffer.concat(chunks);
|
|
15912
|
+
}
|
|
15913
|
+
|
|
15914
|
+
// src/server/projectFiles.ts
|
|
15526
15915
|
var MAX_FILE_BYTES = 2 * 1024 * 1024;
|
|
15527
15916
|
var MAX_DOWNLOAD_BYTES = 16 * 1024 * 1024;
|
|
15528
15917
|
var MAX_BINARY_BYTES = 2.5 * 1024 * 1024;
|
|
15529
15918
|
var MAX_ENTRIES2 = 2e3;
|
|
15919
|
+
var MAX_ZIP_BYTES = 100 * 1024 * 1024;
|
|
15530
15920
|
function toPosix(p) {
|
|
15531
15921
|
return p.split(path30.sep).join("/");
|
|
15532
15922
|
}
|
|
@@ -15802,6 +16192,134 @@ function deleteProjectPaths(workspaceRoot, relPaths) {
|
|
|
15802
16192
|
}
|
|
15803
16193
|
return out;
|
|
15804
16194
|
}
|
|
16195
|
+
function formatBytes(n) {
|
|
16196
|
+
if (n >= 1024 * 1024) return `${(n / (1024 * 1024)).toFixed(1)} MB`;
|
|
16197
|
+
if (n >= 1024) return `${(n / 1024).toFixed(1)} KB`;
|
|
16198
|
+
return `${n} B`;
|
|
16199
|
+
}
|
|
16200
|
+
function renameProjectPath(workspaceRoot, relPath, newName) {
|
|
16201
|
+
const base = projectRoot(workspaceRoot);
|
|
16202
|
+
const rel = (relPath ?? "").trim().replace(/^[/\\]+/, "");
|
|
16203
|
+
if (!rel) throw new Error("\u4E0D\u80FD\u91CD\u547D\u540D\u9879\u76EE\u6839\u76EE\u5F55");
|
|
16204
|
+
const abs = resolveWithin(base, rel);
|
|
16205
|
+
const name = (newName ?? "").trim();
|
|
16206
|
+
if (!name) throw new Error("\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A");
|
|
16207
|
+
if (name === "." || name === "..") throw new Error("\u540D\u79F0\u975E\u6CD5");
|
|
16208
|
+
if (/[/\\]/.test(name)) throw new Error("\u540D\u79F0\u4E0D\u80FD\u5305\u542B\u8DEF\u5F84\u5206\u9694\u7B26");
|
|
16209
|
+
if (!fs23.existsSync(abs)) throw new Error("\u6587\u4EF6\u4E0D\u5B58\u5728");
|
|
16210
|
+
const parent = path30.dirname(abs);
|
|
16211
|
+
const target = path30.join(parent, name);
|
|
16212
|
+
if (!isWithinRoot(base, target)) throw new Error("\u8DEF\u5F84\u8D8A\u754C\uFF08\u8D85\u51FA\u9879\u76EE\u5DE5\u4F5C\u533A\uFF09");
|
|
16213
|
+
if (fs23.existsSync(target)) {
|
|
16214
|
+
let same = false;
|
|
16215
|
+
try {
|
|
16216
|
+
const a = fs23.statSync(target);
|
|
16217
|
+
const b = fs23.statSync(abs);
|
|
16218
|
+
same = a.ino === b.ino && a.dev === b.dev;
|
|
16219
|
+
} catch {
|
|
16220
|
+
same = false;
|
|
16221
|
+
}
|
|
16222
|
+
if (!same) throw new Error(`\u5DF2\u5B58\u5728\u540C\u540D\u6587\u4EF6\u6216\u76EE\u5F55: ${name}`);
|
|
16223
|
+
}
|
|
16224
|
+
if (path30.resolve(target) === path30.resolve(abs)) {
|
|
16225
|
+
return { from: toPosix(path30.relative(base, abs)), path: toPosix(path30.relative(base, abs)) };
|
|
16226
|
+
}
|
|
16227
|
+
try {
|
|
16228
|
+
fs23.renameSync(abs, target);
|
|
16229
|
+
} catch (e) {
|
|
16230
|
+
throw new Error(`\u91CD\u547D\u540D\u5931\u8D25\uFF1A${e instanceof Error ? e.message : String(e)}`);
|
|
16231
|
+
}
|
|
16232
|
+
return { from: toPosix(path30.relative(base, abs)), path: toPosix(path30.relative(base, target)) };
|
|
16233
|
+
}
|
|
16234
|
+
function zipProjectPaths(workspaceRoot, relPaths, opts = {}) {
|
|
16235
|
+
const base = projectRoot(workspaceRoot);
|
|
16236
|
+
const maxBytes = opts.maxBytes && opts.maxBytes > 0 ? opts.maxBytes : MAX_ZIP_BYTES;
|
|
16237
|
+
const rels = (relPaths ?? []).map((x) => (x ?? "").trim().replace(/^[/\\]+/, ""));
|
|
16238
|
+
if (rels.length === 0) throw new Error("\u8BF7\u9009\u62E9\u8981\u538B\u7F29\u7684\u6587\u4EF6\u6216\u76EE\u5F55");
|
|
16239
|
+
if (rels.some((r) => !r)) throw new Error("\u4E0D\u80FD\u538B\u7F29\u9879\u76EE\u6839\u76EE\u5F55");
|
|
16240
|
+
const targets = rels.map((rel) => ({ rel, abs: resolveWithin(base, rel) }));
|
|
16241
|
+
const single = targets.length === 1 ? targets[0].abs : "";
|
|
16242
|
+
const items = [];
|
|
16243
|
+
let total = 0;
|
|
16244
|
+
const overLimit = () => new Error(
|
|
16245
|
+
`\u5171 ${formatBytes(total)}\uFF0C\u8D85\u8FC7 ${formatBytes(maxBytes)} \u4E0A\u9650\uFF0C\u4E0D\u652F\u6301\u538B\u7F29\u4E0B\u8F7D`
|
|
16246
|
+
);
|
|
16247
|
+
const walk = (absDir) => {
|
|
16248
|
+
let dirents;
|
|
16249
|
+
try {
|
|
16250
|
+
dirents = fs23.readdirSync(absDir, { withFileTypes: true });
|
|
16251
|
+
} catch {
|
|
16252
|
+
return 0;
|
|
16253
|
+
}
|
|
16254
|
+
dirents.sort((a, b) => a.name.localeCompare(b.name));
|
|
16255
|
+
let files = 0;
|
|
16256
|
+
for (const d of dirents) {
|
|
16257
|
+
if (d.isSymbolicLink()) continue;
|
|
16258
|
+
const child = path30.join(absDir, d.name);
|
|
16259
|
+
if (d.isDirectory()) {
|
|
16260
|
+
files += walk(child);
|
|
16261
|
+
continue;
|
|
16262
|
+
}
|
|
16263
|
+
if (!d.isFile()) continue;
|
|
16264
|
+
let st;
|
|
16265
|
+
try {
|
|
16266
|
+
st = fs23.statSync(child);
|
|
16267
|
+
} catch {
|
|
16268
|
+
continue;
|
|
16269
|
+
}
|
|
16270
|
+
total += st.size;
|
|
16271
|
+
if (total > maxBytes) throw overLimit();
|
|
16272
|
+
if (items.length >= MAX_ZIP_ENTRIES) {
|
|
16273
|
+
throw new Error(`\u5F52\u6863\u6761\u76EE\u8FC7\u591A\uFF08\u8D85\u8FC7 ${MAX_ZIP_ENTRIES} \u9879\uFF09\uFF0C\u8BF7\u7F29\u5C0F\u8303\u56F4\u540E\u518D\u8BD5`);
|
|
16274
|
+
}
|
|
16275
|
+
items.push({ abs: child, dir: false, size: st.size, mtime: st.mtime });
|
|
16276
|
+
files++;
|
|
16277
|
+
}
|
|
16278
|
+
if (files === 0) {
|
|
16279
|
+
let mtime = /* @__PURE__ */ new Date();
|
|
16280
|
+
try {
|
|
16281
|
+
mtime = fs23.statSync(absDir).mtime;
|
|
16282
|
+
} catch {
|
|
16283
|
+
}
|
|
16284
|
+
items.push({ abs: absDir, dir: true, size: 0, mtime });
|
|
16285
|
+
}
|
|
16286
|
+
return files;
|
|
16287
|
+
};
|
|
16288
|
+
for (const t of targets) {
|
|
16289
|
+
let st;
|
|
16290
|
+
try {
|
|
16291
|
+
st = fs23.statSync(t.abs);
|
|
16292
|
+
} catch {
|
|
16293
|
+
throw new Error(`\u6587\u4EF6\u4E0D\u5B58\u5728: ${t.rel}`);
|
|
16294
|
+
}
|
|
16295
|
+
if (st.isDirectory()) {
|
|
16296
|
+
walk(t.abs);
|
|
16297
|
+
continue;
|
|
16298
|
+
}
|
|
16299
|
+
total += st.size;
|
|
16300
|
+
if (total > maxBytes) throw overLimit();
|
|
16301
|
+
items.push({ abs: t.abs, dir: false, size: st.size, mtime: st.mtime });
|
|
16302
|
+
}
|
|
16303
|
+
const nameOf = (abs) => {
|
|
16304
|
+
const rel = toPosix(path30.relative(single || base, abs));
|
|
16305
|
+
return rel || path30.posix.basename(toPosix(abs));
|
|
16306
|
+
};
|
|
16307
|
+
const zipEntries = items.map((it) => {
|
|
16308
|
+
const name2 = nameOf(it.abs);
|
|
16309
|
+
if (it.dir) return { name: `${name2}/`, mtime: it.mtime };
|
|
16310
|
+
return { name: name2, data: fs23.readFileSync(it.abs), mtime: it.mtime };
|
|
16311
|
+
});
|
|
16312
|
+
const buf = buildZip(zipEntries);
|
|
16313
|
+
const first = targets[0].rel;
|
|
16314
|
+
const name = single ? `${path30.posix.basename(toPosix(first))}.zip` : "archive.zip";
|
|
16315
|
+
return {
|
|
16316
|
+
name,
|
|
16317
|
+
size: buf.length,
|
|
16318
|
+
total,
|
|
16319
|
+
entries: zipEntries.length,
|
|
16320
|
+
base64: buf.toString("base64")
|
|
16321
|
+
};
|
|
16322
|
+
}
|
|
15805
16323
|
|
|
15806
16324
|
// src/server/projectOps.ts
|
|
15807
16325
|
init_cjs_shims();
|
|
@@ -16131,6 +16649,7 @@ function projectStats(manager, tenantId) {
|
|
|
16131
16649
|
|
|
16132
16650
|
// src/server/nodeHost.ts
|
|
16133
16651
|
init_cjs_shims();
|
|
16652
|
+
var import_child_process = require("child_process");
|
|
16134
16653
|
var fs24 = __toESM(require("fs"), 1);
|
|
16135
16654
|
var os9 = __toESM(require("os"), 1);
|
|
16136
16655
|
function diskInfo(pathStr) {
|
|
@@ -16145,6 +16664,64 @@ function diskInfo(pathStr) {
|
|
|
16145
16664
|
return null;
|
|
16146
16665
|
}
|
|
16147
16666
|
}
|
|
16667
|
+
var PSEUDO_FS = /^(devfs|tmpfs|devtmpfs|proc|procfs|sysfs|none|udev|shm|mqueue|devpts|hugetlbfs|debugfs|tracefs|securityfs|pstore|bpf|configfs|fusectl|nsfs|autofs|efivarfs|ramfs|map)$/;
|
|
16668
|
+
function isInternalMount(mount) {
|
|
16669
|
+
if (mount === "/") return false;
|
|
16670
|
+
const prefixes = ["/proc", "/sys", "/run", "/snap"];
|
|
16671
|
+
if (process.platform === "darwin") prefixes.push("/System/Volumes");
|
|
16672
|
+
return prefixes.some((p) => mount === p || mount.startsWith(`${p}/`));
|
|
16673
|
+
}
|
|
16674
|
+
function readOnlyVolumes() {
|
|
16675
|
+
const out = /* @__PURE__ */ new Set();
|
|
16676
|
+
const res = (0, import_child_process.spawnSync)("mount", [], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
|
|
16677
|
+
if (res.error || res.status !== 0 || !res.stdout) return out;
|
|
16678
|
+
for (const line of res.stdout.split("\n")) {
|
|
16679
|
+
const m = line.match(/^.+? on (.+?) \(([^)]*)\)$/);
|
|
16680
|
+
if (!m || m[1] === "/") continue;
|
|
16681
|
+
if (m[2].split(",").some((opt) => opt.trim() === "read-only")) out.add(m[1]);
|
|
16682
|
+
}
|
|
16683
|
+
return out;
|
|
16684
|
+
}
|
|
16685
|
+
function diskList(workspacePath) {
|
|
16686
|
+
const out = [];
|
|
16687
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16688
|
+
const push = (path44, total, free) => {
|
|
16689
|
+
if (!path44 || seen.has(path44) || !Number.isFinite(total) || total <= 0) return;
|
|
16690
|
+
seen.add(path44);
|
|
16691
|
+
out.push({ path: path44, total, free });
|
|
16692
|
+
};
|
|
16693
|
+
if (process.platform === "win32") {
|
|
16694
|
+
for (const letter of "CDEFGHIJKLMNOPQRSTUVWXYZ") {
|
|
16695
|
+
const root = `${letter}:\\`;
|
|
16696
|
+
const d = diskInfo(root);
|
|
16697
|
+
if (d) push(root, d.total, d.free);
|
|
16698
|
+
}
|
|
16699
|
+
} else {
|
|
16700
|
+
const readonly = process.platform === "darwin" ? readOnlyVolumes() : /* @__PURE__ */ new Set();
|
|
16701
|
+
const res = (0, import_child_process.spawnSync)("df", ["-kP"], {
|
|
16702
|
+
encoding: "utf-8",
|
|
16703
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
16704
|
+
});
|
|
16705
|
+
if (!res.error && res.status === 0 && res.stdout) {
|
|
16706
|
+
for (const line of res.stdout.split("\n").slice(1)) {
|
|
16707
|
+
const m = line.trim().match(/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\d+%\s+(.+)$/);
|
|
16708
|
+
if (!m || PSEUDO_FS.test(m[1])) continue;
|
|
16709
|
+
if (/^\/dev\/loop\d+$/.test(m[1])) continue;
|
|
16710
|
+
if (isInternalMount(m[5]) || readonly.has(m[5])) continue;
|
|
16711
|
+
push(m[5], Number(m[2]) * 1024, Number(m[4]) * 1024);
|
|
16712
|
+
}
|
|
16713
|
+
}
|
|
16714
|
+
}
|
|
16715
|
+
const primary = diskInfo(workspacePath);
|
|
16716
|
+
if (primary) {
|
|
16717
|
+
const covered = out.some((d) => {
|
|
16718
|
+
const root = d.path.endsWith("/") || d.path.endsWith("\\") ? d.path : `${d.path}/`;
|
|
16719
|
+
return workspacePath === d.path || workspacePath.startsWith(root);
|
|
16720
|
+
});
|
|
16721
|
+
if (!covered) push(primary.path, primary.total, primary.free);
|
|
16722
|
+
}
|
|
16723
|
+
return out.sort((a, b) => b.total - a.total);
|
|
16724
|
+
}
|
|
16148
16725
|
function networkInfo() {
|
|
16149
16726
|
const out = [];
|
|
16150
16727
|
const ifaces = os9.networkInterfaces();
|
|
@@ -16200,6 +16777,7 @@ function overview(store, manager) {
|
|
|
16200
16777
|
function buildNodeHost(store, manager, diskPath) {
|
|
16201
16778
|
const cpus2 = os9.cpus();
|
|
16202
16779
|
const ov = overview(store, manager);
|
|
16780
|
+
const disks = diskList(diskPath || process.cwd());
|
|
16203
16781
|
return {
|
|
16204
16782
|
nodeId: store.loadNodeId() ?? "",
|
|
16205
16783
|
hostname: os9.hostname(),
|
|
@@ -16207,7 +16785,7 @@ function buildNodeHost(store, manager, diskPath) {
|
|
|
16207
16785
|
arch: process.arch,
|
|
16208
16786
|
release: os9.release(),
|
|
16209
16787
|
uptimeSec: Math.round(os9.uptime()),
|
|
16210
|
-
version: "0.2.
|
|
16788
|
+
version: "0.2.20",
|
|
16211
16789
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
16212
16790
|
cpu: {
|
|
16213
16791
|
count: cpus2.length,
|
|
@@ -16217,6 +16795,7 @@ function buildNodeHost(store, manager, diskPath) {
|
|
|
16217
16795
|
memory: { total: os9.totalmem(), free: os9.freemem() },
|
|
16218
16796
|
network: networkInfo(),
|
|
16219
16797
|
disk: diskInfo(diskPath || process.cwd()),
|
|
16798
|
+
disks,
|
|
16220
16799
|
...ov
|
|
16221
16800
|
};
|
|
16222
16801
|
}
|
|
@@ -17442,6 +18021,41 @@ function createApp(store, manager, opts = {}) {
|
|
|
17442
18021
|
}
|
|
17443
18022
|
}
|
|
17444
18023
|
},
|
|
18024
|
+
{
|
|
18025
|
+
method: "POST",
|
|
18026
|
+
pattern: ["files", "rename"],
|
|
18027
|
+
// 重命名(只改同目录下的名字)
|
|
18028
|
+
fn: (_req, res, { tenant, body }) => {
|
|
18029
|
+
const raw = body ?? {};
|
|
18030
|
+
try {
|
|
18031
|
+
ok(
|
|
18032
|
+
res,
|
|
18033
|
+
renameProjectPath(
|
|
18034
|
+
tenant.workspaceRoot ?? null,
|
|
18035
|
+
String(raw.path ?? ""),
|
|
18036
|
+
String(raw.name ?? "")
|
|
18037
|
+
)
|
|
18038
|
+
);
|
|
18039
|
+
} catch (e) {
|
|
18040
|
+
throw new ApiError(400, "bad_request", e instanceof Error ? e.message : String(e));
|
|
18041
|
+
}
|
|
18042
|
+
}
|
|
18043
|
+
},
|
|
18044
|
+
{
|
|
18045
|
+
method: "POST",
|
|
18046
|
+
pattern: ["files", "zip"],
|
|
18047
|
+
// 压缩下载(多选一起打包;超上限由实现拒绝)
|
|
18048
|
+
fn: (_req, res, { tenant, body }) => {
|
|
18049
|
+
const raw = body ?? {};
|
|
18050
|
+
const paths = Array.isArray(raw.paths) ? raw.paths.map((x) => String(x)) : [];
|
|
18051
|
+
if (paths.length === 0) throw new ApiError(400, "bad_request", "paths \u4E0D\u80FD\u4E3A\u7A7A");
|
|
18052
|
+
try {
|
|
18053
|
+
ok(res, zipProjectPaths(tenant.workspaceRoot ?? null, paths));
|
|
18054
|
+
} catch (e) {
|
|
18055
|
+
throw new ApiError(400, "bad_request", e instanceof Error ? e.message : String(e));
|
|
18056
|
+
}
|
|
18057
|
+
}
|
|
18058
|
+
},
|
|
17445
18059
|
// ---------- 项目(= 租户)管理:控制台多项目视图 ----------
|
|
17446
18060
|
// 仅管理员密钥可用;项目级与会话级接口仍用项目自己的 tenant API Key
|
|
17447
18061
|
// (或管理员密钥 + X-Project-Id 头),互不暴露明文密钥。
|
|
@@ -17500,6 +18114,29 @@ function createApp(store, manager, opts = {}) {
|
|
|
17500
18114
|
ok(res, nodeLlmView(next));
|
|
17501
18115
|
}
|
|
17502
18116
|
},
|
|
18117
|
+
// 大模型账户余额(控制台「余额不足 → 查看余额并充值」用;由节点向 Hub 代查)
|
|
18118
|
+
{
|
|
18119
|
+
method: "GET",
|
|
18120
|
+
pattern: ["node", "llm", "balance"],
|
|
18121
|
+
adminOnly: true,
|
|
18122
|
+
fn: async (_req, res) => {
|
|
18123
|
+
ok(res, await fetchLlmBalance(store));
|
|
18124
|
+
}
|
|
18125
|
+
},
|
|
18126
|
+
// 重新拉取平台内置模型凭据(用户点了「刷新内置模型」,或 Key 在控制台被重置)
|
|
18127
|
+
{
|
|
18128
|
+
method: "POST",
|
|
18129
|
+
pattern: ["node", "llm", "builtin-refresh"],
|
|
18130
|
+
adminOnly: true,
|
|
18131
|
+
fn: async (_req, res) => {
|
|
18132
|
+
const r = await ensureBuiltinProvider(store, { force: true });
|
|
18133
|
+
if (r.status !== "ready") {
|
|
18134
|
+
ok(res, { ok: false, reason: r.reason });
|
|
18135
|
+
return;
|
|
18136
|
+
}
|
|
18137
|
+
ok(res, { ok: true, view: nodeLlmView(store.loadNodeLlm()) });
|
|
18138
|
+
}
|
|
18139
|
+
},
|
|
17503
18140
|
// ---------- 用量(账本 + 汇总 + 价格) ----------
|
|
17504
18141
|
{
|
|
17505
18142
|
method: "GET",
|
|
@@ -17926,7 +18563,7 @@ function createApp(store, manager, opts = {}) {
|
|
|
17926
18563
|
json(res, 200, {
|
|
17927
18564
|
status: "ok",
|
|
17928
18565
|
// 版本让运维/探针能确认线上跑的是哪个构建(更新与回滚据此判断)
|
|
17929
|
-
version: "0.2.
|
|
18566
|
+
version: "0.2.20",
|
|
17930
18567
|
features: { mcp: hasServerMcpConfig() }
|
|
17931
18568
|
});
|
|
17932
18569
|
return;
|
|
@@ -18266,6 +18903,22 @@ async function dispatchFleetCommand(deps, env3) {
|
|
|
18266
18903
|
store.saveNodeLlm(next);
|
|
18267
18904
|
return ok2(nodeLlmView(next));
|
|
18268
18905
|
}
|
|
18906
|
+
/*
|
|
18907
|
+
* 重新拉取平台内置模型(志前 API)。
|
|
18908
|
+
*
|
|
18909
|
+
* 用途:用户在控制台点了「刷新」、或内置模型的 Key 在控制台被重置后需要换新。
|
|
18910
|
+
* 走写链串行——它会改写 connections.json,不能与 update_node_llm 并发。
|
|
18911
|
+
*/
|
|
18912
|
+
// 余额查询:只读、幂等,可进只读并发池
|
|
18913
|
+
case "get_llm_balance":
|
|
18914
|
+
return ok2(await fetchLlmBalance(store));
|
|
18915
|
+
case "refresh_builtin_llm": {
|
|
18916
|
+
const r = await ensureBuiltinProvider(store, { force: true });
|
|
18917
|
+
if (r.status !== "ready") {
|
|
18918
|
+
return ok2({ ok: false, reason: r.reason });
|
|
18919
|
+
}
|
|
18920
|
+
return ok2({ ok: true, view: nodeLlmView(store.loadNodeLlm()) });
|
|
18921
|
+
}
|
|
18269
18922
|
case "get_usage_summary": {
|
|
18270
18923
|
const ledger = manager.usageLedger();
|
|
18271
18924
|
if (!ledger) return ok2({ total: null, groups: [] });
|
|
@@ -18450,6 +19103,24 @@ async function dispatchFleetCommand(deps, env3) {
|
|
|
18450
19103
|
const t = project();
|
|
18451
19104
|
return ok2(searchProjectFiles(t.workspaceRoot ?? null, String(payload.query ?? "")));
|
|
18452
19105
|
}
|
|
19106
|
+
case "rename_path": {
|
|
19107
|
+
const t = project();
|
|
19108
|
+
return ok2(
|
|
19109
|
+
renameProjectPath(
|
|
19110
|
+
t.workspaceRoot ?? null,
|
|
19111
|
+
String(payload.path ?? ""),
|
|
19112
|
+
String(payload.name ?? "")
|
|
19113
|
+
)
|
|
19114
|
+
);
|
|
19115
|
+
}
|
|
19116
|
+
case "zip_download": {
|
|
19117
|
+
const t = project();
|
|
19118
|
+
const raw = payload.paths;
|
|
19119
|
+
const paths = Array.isArray(raw) ? raw.map((x) => String(x)) : [];
|
|
19120
|
+
if (paths.length === 0) throw new ApiError(400, "bad_request", "paths \u4E0D\u80FD\u4E3A\u7A7A");
|
|
19121
|
+
const maxBytes = typeof payload.maxBytes === "number" ? payload.maxBytes : void 0;
|
|
19122
|
+
return ok2(zipProjectPaths(t.workspaceRoot ?? null, paths, { maxBytes }));
|
|
19123
|
+
}
|
|
18453
19124
|
case "list_tools": {
|
|
18454
19125
|
const t = project();
|
|
18455
19126
|
return ok2(buildToolCatalog(t.workspaceRoot ?? process.cwd()));
|
|
@@ -18802,6 +19473,22 @@ function toWireAck(ack) {
|
|
|
18802
19473
|
data: ack.data === void 0 ? void 0 : utf8Encode(JSON.stringify(ack.data))
|
|
18803
19474
|
};
|
|
18804
19475
|
}
|
|
19476
|
+
var ACK_JSON_MAX_BYTES = MAX_FRAME_BYTES - 64 * 1024;
|
|
19477
|
+
function mb(bytes) {
|
|
19478
|
+
return (bytes / (1024 * 1024)).toFixed(1);
|
|
19479
|
+
}
|
|
19480
|
+
function guardAckSize(ack, json2) {
|
|
19481
|
+
if (!ack.ok || ack.data === void 0) return ack;
|
|
19482
|
+
const bytes = Buffer.byteLength(json2, "utf8");
|
|
19483
|
+
if (bytes <= ACK_JSON_MAX_BYTES) return ack;
|
|
19484
|
+
return {
|
|
19485
|
+
reqId: ack.reqId,
|
|
19486
|
+
type: ack.type,
|
|
19487
|
+
ok: false,
|
|
19488
|
+
// 带上实际大小:用户据此能判断「差一点」还是「差很多」,而不是只看到「失败」
|
|
19489
|
+
error: `\u7ED3\u679C\u8FC7\u5927\uFF08${mb(bytes)} MB\uFF09\uFF0C\u8D85\u8FC7\u5355\u5E27\u4F20\u8F93\u4E0A\u9650\uFF08${mb(ACK_JSON_MAX_BYTES)} MB\uFF09\uFF0C\u8BF7\u7F29\u5C0F\u8303\u56F4\u540E\u91CD\u8BD5`
|
|
19490
|
+
};
|
|
19491
|
+
}
|
|
18805
19492
|
function fromWireCommand(env3) {
|
|
18806
19493
|
let payload = {};
|
|
18807
19494
|
if (env3.payload && env3.payload.length > 0) {
|
|
@@ -19207,6 +19894,7 @@ var READONLY_CMD_TYPES = /* @__PURE__ */ new Set([
|
|
|
19207
19894
|
"get_node_llm",
|
|
19208
19895
|
"list_node_llm_models",
|
|
19209
19896
|
"get_usage_summary",
|
|
19897
|
+
"get_llm_balance",
|
|
19210
19898
|
"get_usage_records",
|
|
19211
19899
|
"get_usage_pricing",
|
|
19212
19900
|
"list_projects",
|
|
@@ -19631,7 +20319,7 @@ var FleetNodeBridge = class {
|
|
|
19631
20319
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
19632
20320
|
platform: process.platform,
|
|
19633
20321
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
19634
|
-
version: "0.2.
|
|
20322
|
+
version: "0.2.20",
|
|
19635
20323
|
ip: primaryIp()
|
|
19636
20324
|
};
|
|
19637
20325
|
}
|
|
@@ -19729,7 +20417,7 @@ var FleetNodeBridge = class {
|
|
|
19729
20417
|
label: this.opts.deps.store.loadNodeLabel() ?? void 0,
|
|
19730
20418
|
platform: process.platform,
|
|
19731
20419
|
mode: process.env.NODE_MODE ?? "standalone",
|
|
19732
|
-
version: "0.2.
|
|
20420
|
+
version: "0.2.20",
|
|
19733
20421
|
ip: primaryIp(),
|
|
19734
20422
|
projects,
|
|
19735
20423
|
totals,
|
|
@@ -19891,7 +20579,13 @@ var FleetNodeBridge = class {
|
|
|
19891
20579
|
const stamped = { ...ack, reqId: env3.reqId, type: env3.type };
|
|
19892
20580
|
const json2 = JSON.stringify(stamped);
|
|
19893
20581
|
const __t1 = dbgNow();
|
|
19894
|
-
|
|
20582
|
+
const payload = guardAckSize(stamped, json2);
|
|
20583
|
+
if (payload !== stamped) {
|
|
20584
|
+
console.warn(
|
|
20585
|
+
`[fleet] ${env3.type} \u56DE\u6267 ${(json2.length / 1024 / 1024).toFixed(1)}MB \u8D85\u8FC7\u5355\u5E27\u4E0A\u9650\uFF0C\u5DF2\u964D\u7EA7\u4E3A\u9519\u8BEF\u56DE\u6267`
|
|
20586
|
+
);
|
|
20587
|
+
}
|
|
20588
|
+
this._send({ kind: "ack", clientId: env3.clientId, ack: payload });
|
|
19895
20589
|
dbgMs(
|
|
19896
20590
|
"publishAck",
|
|
19897
20591
|
__t0,
|
|
@@ -21935,7 +22629,9 @@ function seedDemoTenant(store) {
|
|
|
21935
22629
|
// 未显式指定时随机生成:固定默认密钥一旦随 HOST=0.0.0.0 暴露到公网,等于公开凭据。
|
|
21936
22630
|
// 只在首次创建时生成并落盘,后续启动沿用磁盘上的值(启动日志会打印完整密钥)。
|
|
21937
22631
|
apiKey: env2("TENANT_API_KEY") ?? generateApiKey(),
|
|
21938
|
-
|
|
22632
|
+
// 不再硬编码具体厂商型号:志前 API 只认 deepseek-flash,写死 deepseek-v4-flash
|
|
22633
|
+
// 会让新装节点的第一次请求 404。默认值统一走 defaultTenantModel(见 nodeLlm.ts)。
|
|
22634
|
+
model: defaultTenantModel(store),
|
|
21939
22635
|
provider: {
|
|
21940
22636
|
apiKey: env2("OPENAI_API_KEY"),
|
|
21941
22637
|
baseURL: env2("OPENAI_BASE_URL")
|
|
@@ -22075,6 +22771,8 @@ function startServer(opts = {}) {
|
|
|
22075
22771
|
const store = new Store(dataDir);
|
|
22076
22772
|
const demo = seedDemoTenant(store);
|
|
22077
22773
|
syncTenantModels(store);
|
|
22774
|
+
const nodeModel = nodeDefaultProvider(store)?.model;
|
|
22775
|
+
if (nodeModel) adoptBuiltinModelForTenants(store, nodeModel);
|
|
22078
22776
|
const usageLedger = new UsageLedger(dataDir);
|
|
22079
22777
|
usageLedger.init();
|
|
22080
22778
|
const manager = new SessionManager(store, void 0, { usage: usageLedger });
|
|
@@ -22218,8 +22916,12 @@ function startServer(opts = {}) {
|
|
|
22218
22916
|
if (initialCred) {
|
|
22219
22917
|
connectFleet(initialCred);
|
|
22220
22918
|
} else if (opts.autoEnroll) {
|
|
22221
|
-
void fleetController.enroll(opts.autoEnroll).then((st) =>
|
|
22919
|
+
void fleetController.enroll(opts.autoEnroll).then((st) => {
|
|
22920
|
+
console.log(`[fleet] \u5DF2\u81EA\u52A8\u63A5\u5165\uFF0C\u8282\u70B9 ${st.nodeId}\uFF08${st.gatewayUrl}\uFF09`);
|
|
22921
|
+
scheduleBuiltinProvider(store, (m) => console.log(m));
|
|
22922
|
+
}).catch((e) => console.warn(`[fleet] \u81EA\u52A8\u63A5\u5165\u5931\u8D25\uFF08\u53EF\u7A0D\u540E /link \u91CD\u8BD5\uFF09: ${e instanceof Error ? e.message : e}`));
|
|
22222
22923
|
}
|
|
22924
|
+
if (initialCred) scheduleBuiltinProvider(store, (m) => console.log(m));
|
|
22223
22925
|
const pairingCodes = new PairingCodeStore();
|
|
22224
22926
|
const qq = new QqManager({
|
|
22225
22927
|
store,
|
|
@@ -22794,7 +23496,7 @@ ${envDump()}`);
|
|
|
22794
23496
|
}
|
|
22795
23497
|
|
|
22796
23498
|
// src/cli/index.ts
|
|
22797
|
-
var execAsync2 = (0, import_util.promisify)(
|
|
23499
|
+
var execAsync2 = (0, import_util.promisify)(import_child_process2.exec);
|
|
22798
23500
|
if (enableDebug(process.argv)) {
|
|
22799
23501
|
logEnvironment();
|
|
22800
23502
|
}
|
|
@@ -23273,7 +23975,10 @@ async function connectWizard() {
|
|
|
23273
23975
|
break;
|
|
23274
23976
|
}
|
|
23275
23977
|
cliLog(`\u274C \u81EA\u68C0\u5931\u8D25: ${probe.error}${probe.code ? ` | ${probe.code}` : ""}`);
|
|
23276
|
-
for (const hint of
|
|
23978
|
+
for (const hint of [
|
|
23979
|
+
...authErrorHints(probe.error ?? "", probe.code ?? ""),
|
|
23980
|
+
...paramErrorHints(probe.error ?? "", probe.code ?? "")
|
|
23981
|
+
]) {
|
|
23277
23982
|
cliLog(` \u{1F4A1} ${hint}`);
|
|
23278
23983
|
}
|
|
23279
23984
|
const keep = (await question("\u91CD\u65B0\u9009\u62E9\u6A21\u578B (\u56DE\u8F66\u91CD\u9009) / \u8F93\u5165 y \u4ECD\u4F7F\u7528\u8BE5\u6A21\u578B: ")).trim().toLowerCase();
|
|
@@ -23507,7 +24212,7 @@ async function offerTerminalSetup(engine, canUseAgent) {
|
|
|
23507
24212
|
}
|
|
23508
24213
|
var KNOWN_SUBCOMMANDS = /* @__PURE__ */ new Set(["link", "serve", "update", "rename"]);
|
|
23509
24214
|
function cliVersion() {
|
|
23510
|
-
const env3 = "0.2.
|
|
24215
|
+
const env3 = "0.2.20"?.trim();
|
|
23511
24216
|
if (env3) return env3;
|
|
23512
24217
|
try {
|
|
23513
24218
|
const req2 = (0, import_module.createRequire)(importMetaUrl);
|
|
@@ -24020,6 +24725,12 @@ async function main() {
|
|
|
24020
24725
|
cliLog(`\u274C \u672A\u627E\u5230\u4F9B\u5E94\u5546: ${arg}`);
|
|
24021
24726
|
break;
|
|
24022
24727
|
}
|
|
24728
|
+
if (target.id === BUILTIN_PROVIDER_ID) {
|
|
24729
|
+
cliLog(
|
|
24730
|
+
"\u274C \u5E73\u53F0\u5185\u7F6E\u6A21\u578B\u4E0D\u53EF\u5220\u9664\uFF08\u63A5\u5165 Hub \u540E\u81EA\u52A8\u914D\u7F6E\uFF0CKey \u7531\u5E73\u53F0\u6258\u7BA1\uFF09\u3002\n \u5982\u9700\u6539\u7528\u5176\u5B83\u6A21\u578B\uFF1A/connect \u9009\u62E9\u6216\u6DFB\u52A0\u4F9B\u5E94\u5546\u540E\u8BBE\u4E3A\u9ED8\u8BA4\u3002"
|
|
24731
|
+
);
|
|
24732
|
+
break;
|
|
24733
|
+
}
|
|
24023
24734
|
if (removeConnection(target.id)) {
|
|
24024
24735
|
currentConnection = loadConnection();
|
|
24025
24736
|
engine = buildEngine(SESSION_ID);
|