engine7 7.1.94 → 7.1.95
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +90 -16
- package/dist/engine-startup.mjs +253 -31
- package/dist/main.mjs +258 -36
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -27228,12 +27228,17 @@ var init_cli_doctor = __esm({
|
|
|
27228
27228
|
var provision_free_exports = {};
|
|
27229
27229
|
__export(provision_free_exports, {
|
|
27230
27230
|
loadOrCreateInstallIdentity: () => loadOrCreateInstallIdentity,
|
|
27231
|
-
provisionFreeToken: () => provisionFreeToken
|
|
27231
|
+
provisionFreeToken: () => provisionFreeToken,
|
|
27232
|
+
readInstallIdentity: () => readInstallIdentity,
|
|
27233
|
+
writeIdentityContactEmail: () => writeIdentityContactEmail
|
|
27232
27234
|
});
|
|
27233
27235
|
import { randomBytes as randomBytes6, randomUUID as randomUUID9 } from "node:crypto";
|
|
27234
27236
|
import { chmodSync as chmodSync2, existsSync as existsSync31, mkdirSync as mkdirSync19, readFileSync as readFileSync39, writeFileSync as writeFileSync20 } from "node:fs";
|
|
27235
27237
|
import { dirname as dirname12, join as join49 } from "node:path";
|
|
27236
27238
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
27239
|
+
function readContactEmailOf(parsed) {
|
|
27240
|
+
return typeof parsed?.contactEmail === "string" ? parsed.contactEmail.trim() : "";
|
|
27241
|
+
}
|
|
27237
27242
|
function loadOrCreateInstallIdentity(stateDir) {
|
|
27238
27243
|
const file2 = join49(stateDir, IDENTITY_FILE);
|
|
27239
27244
|
if (existsSync31(file2)) {
|
|
@@ -27248,7 +27253,12 @@ function loadOrCreateInstallIdentity(stateDir) {
|
|
|
27248
27253
|
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
27249
27254
|
throw new Error(`${IDENTITY_FILE} \u7F3A installId / installSecret \u5B57\u6BB5`);
|
|
27250
27255
|
}
|
|
27251
|
-
|
|
27256
|
+
const email = readContactEmailOf(parsed);
|
|
27257
|
+
return {
|
|
27258
|
+
installId: parsed.installId,
|
|
27259
|
+
installSecret: parsed.installSecret,
|
|
27260
|
+
...email ? { contactEmail: email } : {}
|
|
27261
|
+
};
|
|
27252
27262
|
}
|
|
27253
27263
|
const identity = {
|
|
27254
27264
|
// 服务端校验 installId 长度为 8..36、只允许字母数字和连字符;uuid 正好符合
|
|
@@ -27264,6 +27274,32 @@ function loadOrCreateInstallIdentity(stateDir) {
|
|
|
27264
27274
|
}
|
|
27265
27275
|
return identity;
|
|
27266
27276
|
}
|
|
27277
|
+
function readInstallIdentity(stateDir) {
|
|
27278
|
+
try {
|
|
27279
|
+
const parsed = JSON.parse(readFileSync39(join49(stateDir, IDENTITY_FILE), "utf8"));
|
|
27280
|
+
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") return null;
|
|
27281
|
+
const email = readContactEmailOf(parsed);
|
|
27282
|
+
return {
|
|
27283
|
+
installId: parsed.installId,
|
|
27284
|
+
installSecret: parsed.installSecret,
|
|
27285
|
+
...email ? { contactEmail: email } : {}
|
|
27286
|
+
};
|
|
27287
|
+
} catch {
|
|
27288
|
+
return null;
|
|
27289
|
+
}
|
|
27290
|
+
}
|
|
27291
|
+
function writeIdentityContactEmail(stateDir, email) {
|
|
27292
|
+
const identity = loadOrCreateInstallIdentity(stateDir);
|
|
27293
|
+
const trimmed = email.trim();
|
|
27294
|
+
const next = { ...identity, contactEmail: trimmed };
|
|
27295
|
+
const file2 = join49(stateDir, IDENTITY_FILE);
|
|
27296
|
+
mkdirSync19(stateDir, { recursive: true });
|
|
27297
|
+
writeFileSync20(file2, JSON.stringify(next, null, 2) + "\n", { mode: 384 });
|
|
27298
|
+
try {
|
|
27299
|
+
chmodSync2(file2, 384);
|
|
27300
|
+
} catch {
|
|
27301
|
+
}
|
|
27302
|
+
}
|
|
27267
27303
|
function readEngineVersion() {
|
|
27268
27304
|
try {
|
|
27269
27305
|
return JSON.parse(readFileSync39(join49(dirname12(__filename), "..", "package.json"), "utf8")).version || "unknown";
|
|
@@ -27278,7 +27314,14 @@ async function provisionFreeToken(opts) {
|
|
|
27278
27314
|
const res = await doFetch(url, {
|
|
27279
27315
|
method: "POST",
|
|
27280
27316
|
headers: { "Content-Type": "application/json" },
|
|
27281
|
-
|
|
27317
|
+
// 显式列字段,**不要用 `...identity` 展开**:InstallIdentity 加了 contactEmail
|
|
27318
|
+
// 之后,展开会把邮箱也发到发号端点——协议悄悄变了,而服务端只认这三个字段。
|
|
27319
|
+
// (provision-free.test.ts 里有一条断言守这个。)
|
|
27320
|
+
body: JSON.stringify({
|
|
27321
|
+
installId: identity.installId,
|
|
27322
|
+
installSecret: identity.installSecret,
|
|
27323
|
+
engineVersion: readEngineVersion()
|
|
27324
|
+
})
|
|
27282
27325
|
});
|
|
27283
27326
|
const text = await res.text();
|
|
27284
27327
|
let body;
|
|
@@ -28165,6 +28208,13 @@ import * as fs2 from "node:fs";
|
|
|
28165
28208
|
// src/cli-init-config.ts
|
|
28166
28209
|
import * as path2 from "node:path";
|
|
28167
28210
|
var SCHEMA_VERSION = 1;
|
|
28211
|
+
var FREE_TIER_RELAY_URL = "https://www.twinsun.top:8866";
|
|
28212
|
+
function isFreeTier(v) {
|
|
28213
|
+
return v.freeTier === true || v.primaryProvider === "7yi";
|
|
28214
|
+
}
|
|
28215
|
+
function resolveRelayUrl(relayArg, env = process.env) {
|
|
28216
|
+
return (relayArg || "").trim() || (env.E7_RELAY_URL || "").trim() || FREE_TIER_RELAY_URL;
|
|
28217
|
+
}
|
|
28168
28218
|
var DEFAULT_PRIMARY_MODEL = {
|
|
28169
28219
|
dashscope: "dashscope/qwen3.8-max",
|
|
28170
28220
|
minimax: "minimax/MiniMax-M3",
|
|
@@ -28245,7 +28295,13 @@ var PROVIDER_DEFS = {
|
|
|
28245
28295
|
// 引擎免费档的中转站。baseUrl 是兜底值——真正的权威值来自领号响应
|
|
28246
28296
|
// (服务端按请求 Host 自报地址),由安装器作为 customBaseUrl 下发。
|
|
28247
28297
|
// 这样挪机器、换域名只改服务端,不用重发安装包。
|
|
28248
|
-
|
|
28298
|
+
//
|
|
28299
|
+
// ⚠️ 0921 修:这里原本写的是 `https://www.twinsun.top/v1`(443),而 **443 上不是
|
|
28300
|
+
// 中转站**(实测回的是另一个服务的 FastAPI 404)。安装器那条路每次都会下发
|
|
28301
|
+
// customBaseUrl 把它盖掉,所以正式装机撞不到;但**终端向导选 7yi 时不问 baseUrl**,
|
|
28302
|
+
// 直接落到这个兜底值——于是命令行用户拿到的是「号领到了、引擎起来了、一发消息就废」。
|
|
28303
|
+
// 用常量拼,别再手写一遍(漏端口就是这个坑)。
|
|
28304
|
+
baseUrl: `${FREE_TIER_RELAY_URL}/v1`,
|
|
28249
28305
|
api: "anthropic",
|
|
28250
28306
|
models: [
|
|
28251
28307
|
// ⚠️ contextWindow **不能照抄 1000000**。
|
|
@@ -28365,9 +28421,9 @@ function generateConfig(v) {
|
|
|
28365
28421
|
// 自拍(§4.3):免费档必须显式写 provider:'relay'。不写的话 getProvider()
|
|
28366
28422
|
// 会落回默认值 'fal',而免费装机没有 fal key——第一次自拍就失败。
|
|
28367
28423
|
// 非免费档只在用户真给了形象时才写这个块,且不替他决定 provider。
|
|
28368
|
-
...v
|
|
28424
|
+
...isFreeTier(v) || v.selfiePhotoRelPath || v.selfiePortraitDesc ? {
|
|
28369
28425
|
my_selfie: {
|
|
28370
|
-
...v
|
|
28426
|
+
...isFreeTier(v) ? { provider: "relay" } : {},
|
|
28371
28427
|
...v.selfiePhotoRelPath ? { references: [{ name: "portrait", path: v.selfiePhotoRelPath }] } : {},
|
|
28372
28428
|
// 只在没有照片时才写描述——两个都给的话以照片为准,写进去会让人以为
|
|
28373
28429
|
// 描述也生效了(冷启读的就是这个键)
|
|
@@ -28415,7 +28471,7 @@ function generateConfig(v) {
|
|
|
28415
28471
|
debounceMs: 5e3,
|
|
28416
28472
|
// 免费档的装机目标是「能对话、能看图、能自拍」,这两个 flag 默认 false
|
|
28417
28473
|
// (src/config/features.ts)。显式打开,它们是声明这两件事的地方。
|
|
28418
|
-
...v
|
|
28474
|
+
...isFreeTier(v) ? { selfie: true, eyes: true } : {}
|
|
28419
28475
|
}
|
|
28420
28476
|
}
|
|
28421
28477
|
},
|
|
@@ -28581,6 +28637,13 @@ function validate(a) {
|
|
|
28581
28637
|
if (a.timezone !== void 0 && !isValidTimezone(a.timezone)) {
|
|
28582
28638
|
throw new Error(`timezone \u975E\u6CD5: ${a.timezone}\uFF08\u8981 IANA \u540D\uFF0C\u5982 Asia/Shanghai\u3001Europe/Malta\uFF09`);
|
|
28583
28639
|
}
|
|
28640
|
+
if (a.contactEmail !== void 0 && a.contactEmail !== null && a.contactEmail !== "") {
|
|
28641
|
+
if (typeof a.contactEmail !== "string") throw new Error("contactEmail \u5FC5\u987B\u662F\u5B57\u7B26\u4E32");
|
|
28642
|
+
const t = a.contactEmail.trim();
|
|
28643
|
+
if (t && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)) {
|
|
28644
|
+
throw new Error(`contactEmail \u4E0D\u662F\u5408\u6CD5\u90AE\u7BB1: ${t}`);
|
|
28645
|
+
}
|
|
28646
|
+
}
|
|
28584
28647
|
if (a.feishu?.mode !== void 0 && !VALID_CHANNEL_MODES.includes(a.feishu.mode)) {
|
|
28585
28648
|
throw new Error(`feishu.mode \u975E\u6CD5: ${a.feishu.mode}\uFF08\u53EF\u9009: ${VALID_CHANNEL_MODES.join(" / ")}\uFF09`);
|
|
28586
28649
|
}
|
|
@@ -28609,6 +28672,11 @@ function loadInitAnswers(filePath) {
|
|
|
28609
28672
|
throw new Error(`answers \u6587\u4EF6\u4E0D\u662F\u5408\u6CD5 JSON: ${e.message}`);
|
|
28610
28673
|
}
|
|
28611
28674
|
validate(parsed);
|
|
28675
|
+
if (typeof parsed.contactEmail === "string") {
|
|
28676
|
+
const t = parsed.contactEmail.trim();
|
|
28677
|
+
if (t) parsed.contactEmail = t;
|
|
28678
|
+
else delete parsed.contactEmail;
|
|
28679
|
+
}
|
|
28612
28680
|
return parsed;
|
|
28613
28681
|
}
|
|
28614
28682
|
function buildConfigValuesFromAnswers(stateDir, a, existing = {}) {
|
|
@@ -29399,16 +29467,16 @@ async function main() {
|
|
|
29399
29467
|
}
|
|
29400
29468
|
if (subcommand === "provision-free") {
|
|
29401
29469
|
let relay = "";
|
|
29470
|
+
let relayFromArg = false;
|
|
29402
29471
|
let stateDir = "";
|
|
29403
29472
|
for (let i = 1; i < args.length; i++) {
|
|
29404
|
-
if (args[i] === "--relay" && args[i + 1])
|
|
29405
|
-
|
|
29406
|
-
|
|
29407
|
-
|
|
29408
|
-
console.error("\u7528\u6CD5\uFF1Aengine7 provision-free --relay <\u4E2D\u8F6C\u7AD9\u5730\u5740> --state-dir <\u76EE\u5F55>");
|
|
29409
|
-
console.error(" --relay \u662F\u5B89\u88C5\u5668\u4E0B\u53D1\u7684\u9886\u53F7\u5730\u5740\uFF0C\u4E0D\u662F\u6A21\u578B baseUrl\uFF08\u540E\u8005\u4EE5\u9886\u53F7\u54CD\u5E94\u4E3A\u51C6\uFF09");
|
|
29410
|
-
process.exit(1);
|
|
29473
|
+
if (args[i] === "--relay" && args[i + 1]) {
|
|
29474
|
+
relay = args[++i].trim();
|
|
29475
|
+
relayFromArg = true;
|
|
29476
|
+
} else if (args[i] === "--state-dir" && args[i + 1]) stateDir = args[++i].trim();
|
|
29411
29477
|
}
|
|
29478
|
+
relay = resolveRelayUrl(relay, process.env);
|
|
29479
|
+
if (!relayFromArg) console.error(` \u4E2D\u8F6C\u7AD9: ${relay}\uFF08\u8981\u6362\u5730\u5740\u7528 --relay <\u5730\u5740>\uFF09`);
|
|
29412
29480
|
const { resolveStateDirFromArgs: resolveStateDirFromArgs2 } = await Promise.resolve().then(() => (init_cli_doctor(), cli_doctor_exports));
|
|
29413
29481
|
stateDir = stateDir ? path33.resolve(stateDir) : resolveStateDirFromArgs2(args.slice(1));
|
|
29414
29482
|
try {
|
|
@@ -30225,11 +30293,17 @@ WantedBy=default.target`;
|
|
|
30225
30293
|
values = await interactiveConfig(rl, getDefaultValues(opts.stateDir));
|
|
30226
30294
|
rl.close();
|
|
30227
30295
|
}
|
|
30228
|
-
|
|
30296
|
+
{
|
|
30297
|
+
const { loadOrCreateInstallIdentity: loadOrCreateInstallIdentity2, writeIdentityContactEmail: writeIdentityContactEmail2 } = await Promise.resolve().then(() => (init_provision_free(), provision_free_exports));
|
|
30298
|
+
loadOrCreateInstallIdentity2(opts.stateDir);
|
|
30299
|
+
const contactEmail = (answers?.contactEmail || "").trim();
|
|
30300
|
+
if (contactEmail) writeIdentityContactEmail2(opts.stateDir, contactEmail);
|
|
30301
|
+
}
|
|
30302
|
+
if (isFreeTier(values)) {
|
|
30229
30303
|
const envName = values.primaryProvider.toUpperCase().replace(/[^A-Z0-9_]/g, "_") + "_API_KEY";
|
|
30230
30304
|
if (!readSecretsValue(opts.stateDir, envName)) {
|
|
30231
30305
|
throw new Error(
|
|
30232
|
-
`\u514D\u8D39\u6863\u7F3A\u5C11\u4EE4\u724C\uFF1Asecrets \u91CC\u6CA1\u6709 ${envName}\u3002\u8BF7\u5148\u6267\u884C engine7 provision-free --
|
|
30306
|
+
`\u514D\u8D39\u6863\u7F3A\u5C11\u4EE4\u724C\uFF1Asecrets \u91CC\u6CA1\u6709 ${envName}\u3002\u8BF7\u5148\u6267\u884C engine7 provision-free --state-dir ${opts.stateDir} \u9886\u53F7\uFF0C\u518D\u8DD1 init\u3002`
|
|
30233
30307
|
);
|
|
30234
30308
|
}
|
|
30235
30309
|
}
|
package/dist/engine-startup.mjs
CHANGED
|
@@ -8077,26 +8077,26 @@ async function writeToMailbox(recipientName, message, teamName) {
|
|
|
8077
8077
|
await writeFile2(inboxPath, "[]", { encoding: "utf-8", flag: "wx" });
|
|
8078
8078
|
} catch {
|
|
8079
8079
|
}
|
|
8080
|
-
const
|
|
8080
|
+
const release3 = await acquireLock(inboxPath);
|
|
8081
8081
|
try {
|
|
8082
8082
|
const messages = await readMailbox(recipientName, teamName);
|
|
8083
8083
|
messages.push({ ...message, read: false });
|
|
8084
8084
|
await writeFile2(inboxPath, JSON.stringify(messages, null, 2), "utf-8");
|
|
8085
8085
|
console.log(`[mailbox] Wrote message to ${recipientName} from ${message.from} (team=${teamName || "default"}, inbox=${inboxPath})`);
|
|
8086
8086
|
} finally {
|
|
8087
|
-
await
|
|
8087
|
+
await release3();
|
|
8088
8088
|
}
|
|
8089
8089
|
}
|
|
8090
8090
|
async function markMessagesAsRead(agentName, teamName) {
|
|
8091
8091
|
const inboxPath = getInboxPath(agentName, teamName);
|
|
8092
|
-
const
|
|
8092
|
+
const release3 = await acquireLock(inboxPath);
|
|
8093
8093
|
try {
|
|
8094
8094
|
const messages = await readMailbox(agentName, teamName);
|
|
8095
8095
|
if (messages.length === 0) return;
|
|
8096
8096
|
for (const m of messages) m.read = true;
|
|
8097
8097
|
await writeFile2(inboxPath, JSON.stringify(messages, null, 2), "utf-8");
|
|
8098
8098
|
} finally {
|
|
8099
|
-
await
|
|
8099
|
+
await release3();
|
|
8100
8100
|
}
|
|
8101
8101
|
}
|
|
8102
8102
|
async function clearMailbox(agentName, teamName) {
|
|
@@ -9927,7 +9927,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
9927
9927
|
}
|
|
9928
9928
|
// ── md 读(proactive 消费):开窗预测(全 owner 扫描,end>=今天)──
|
|
9929
9929
|
getOpenPredictions(now, limit = 50) {
|
|
9930
|
-
const
|
|
9930
|
+
const today2 = todayKey(now);
|
|
9931
9931
|
const out = [];
|
|
9932
9932
|
const usersDir = join22(this.root, "users");
|
|
9933
9933
|
if (!existsSync12(usersDir)) return out;
|
|
@@ -9950,7 +9950,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
9950
9950
|
const text = ((block.match(/### Foresight\s*\n+([\s\S]*?)(?:\n### Evidence|$)/) ?? [])[1] ?? "").trim();
|
|
9951
9951
|
const evidence = ((block.match(/### Evidence\s*\n+([\s\S]*?)$/) ?? [])[1] ?? "").trim();
|
|
9952
9952
|
if (!end || !start || !text) continue;
|
|
9953
|
-
if (end <
|
|
9953
|
+
if (end < today2) continue;
|
|
9954
9954
|
out.push({ ownerId: owner.name, startDate: start, endDate: end, content: text.replace(/\n+/g, " ").slice(0, 200), evidence: evidence.replace(/\n+/g, " ").slice(0, 120) });
|
|
9955
9955
|
if (out.length >= limit) return out;
|
|
9956
9956
|
}
|
|
@@ -13491,7 +13491,7 @@ function loadForesightEntries(everosRoot, now, userId, ownerFilter) {
|
|
|
13491
13491
|
return entries2.slice();
|
|
13492
13492
|
}
|
|
13493
13493
|
function parseForesightEntries(everosRoot, now, userId) {
|
|
13494
|
-
const
|
|
13494
|
+
const today2 = todayKey(now);
|
|
13495
13495
|
let files;
|
|
13496
13496
|
if (userId) {
|
|
13497
13497
|
const ownDir = join29(everosRoot, userId, "default_project", "users", userId, ".foresights");
|
|
@@ -13516,7 +13516,7 @@ function parseForesightEntries(everosRoot, now, userId) {
|
|
|
13516
13516
|
const end = (block.match(/\*\*end_time\*\*:\s*(\d{4}-\d{2}-\d{2})/) ?? [])[1];
|
|
13517
13517
|
const text = ((block.match(/### Foresight\s*\n+([\s\S]*?)(?:\n### Evidence|$)/) ?? [])[1] ?? "").trim();
|
|
13518
13518
|
if (!start || !end || !text) continue;
|
|
13519
|
-
if (end <
|
|
13519
|
+
if (end < today2) continue;
|
|
13520
13520
|
const evidence = ((block.match(/### Evidence\s*\n+([\s\S]*?)$/) ?? [])[1] ?? "").trim();
|
|
13521
13521
|
const blockOwner = (block.match(/\*\*owner_id\*\*:\s*(\S+)/) ?? [])[1] ?? fileOwner;
|
|
13522
13522
|
const key = text.replace(/\s+/g, "");
|
|
@@ -21454,7 +21454,7 @@ function isPermittedRedirect(original, redirect) {
|
|
|
21454
21454
|
async function fetchWithRedirects(url, signal, depth = 0) {
|
|
21455
21455
|
if (depth > MAX_REDIRECTS) throw new Error(`\u91CD\u5B9A\u5411\u6B21\u6570\u8FC7\u591A (>${MAX_REDIRECTS})`);
|
|
21456
21456
|
const controller = new AbortController();
|
|
21457
|
-
const timeoutId = setTimeout(() => controller.abort(),
|
|
21457
|
+
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS2);
|
|
21458
21458
|
const onSignalAbort = () => controller.abort();
|
|
21459
21459
|
signal.addEventListener("abort", onSignalAbort, { once: true });
|
|
21460
21460
|
try {
|
|
@@ -21497,14 +21497,14 @@ function getTurndown() {
|
|
|
21497
21497
|
}
|
|
21498
21498
|
return td;
|
|
21499
21499
|
}
|
|
21500
|
-
var MAX_URL_LENGTH, MAX_CONTENT_LENGTH,
|
|
21500
|
+
var MAX_URL_LENGTH, MAX_CONTENT_LENGTH, FETCH_TIMEOUT_MS2, MAX_REDIRECTS, td;
|
|
21501
21501
|
var init_web_fetch = __esm({
|
|
21502
21502
|
"src/tools/web-fetch.ts"() {
|
|
21503
21503
|
"use strict";
|
|
21504
21504
|
init_registry();
|
|
21505
21505
|
MAX_URL_LENGTH = 2e3;
|
|
21506
21506
|
MAX_CONTENT_LENGTH = 10 * 1024 * 1024;
|
|
21507
|
-
|
|
21507
|
+
FETCH_TIMEOUT_MS2 = 6e4;
|
|
21508
21508
|
MAX_REDIRECTS = 10;
|
|
21509
21509
|
registry.register({
|
|
21510
21510
|
name: "web_fetch",
|
|
@@ -21575,7 +21575,7 @@ var init_web_fetch = __esm({
|
|
|
21575
21575
|
|
|
21576
21576
|
// src/tools/wechat/wx-query.ts
|
|
21577
21577
|
var wx_query_exports = {};
|
|
21578
|
-
import { join as
|
|
21578
|
+
import { join as join56 } from "node:path";
|
|
21579
21579
|
function getDescription() {
|
|
21580
21580
|
return `\u67E5\u8BE2\u7FC0\u54E5\u7684\u5FAE\u4FE1\u6D88\u606F\uFF08\u7F13\u5B58\u89E3\u5BC6\u540E\u7684\u672C\u5730\u6570\u636E\u5E93\uFF09\u3002
|
|
21581
21581
|
|
|
@@ -21610,8 +21610,8 @@ var init_wx_query = __esm({
|
|
|
21610
21610
|
"use strict";
|
|
21611
21611
|
init_registry();
|
|
21612
21612
|
init_live();
|
|
21613
|
-
STATE_DIR = process.env.ENGINE7_STATE_DIR ||
|
|
21614
|
-
SCRIPT =
|
|
21613
|
+
STATE_DIR = process.env.ENGINE7_STATE_DIR || join56(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
|
|
21614
|
+
SCRIPT = join56("/Users/chongzhang/work/twinsun-hearth/engine", "src", "tools", "wechat", "wx_query.py");
|
|
21615
21615
|
PYTHON = "python3";
|
|
21616
21616
|
registry.register({
|
|
21617
21617
|
name: "wx_query",
|
|
@@ -22532,8 +22532,8 @@ async function doReloadConfigInner(config, deps, provider, force = false) {
|
|
|
22532
22532
|
const savedConfigPath = config._configFilePath;
|
|
22533
22533
|
let reloadConfigPath = savedConfigPath;
|
|
22534
22534
|
if (!fs10.existsSync(reloadConfigPath)) {
|
|
22535
|
-
const
|
|
22536
|
-
const __dirname = path10.dirname(
|
|
22535
|
+
const __filename2 = fileURLToPath(import.meta.url);
|
|
22536
|
+
const __dirname = path10.dirname(__filename2);
|
|
22537
22537
|
const engineConfigsDir = path10.resolve(__dirname, "../configs");
|
|
22538
22538
|
const altPath = path10.join(engineConfigsDir, path10.basename(savedConfigPath));
|
|
22539
22539
|
if (fs10.existsSync(altPath)) {
|
|
@@ -22847,20 +22847,20 @@ function acquireEngineLock(stateDir) {
|
|
|
22847
22847
|
} catch (err) {
|
|
22848
22848
|
console.warn(`[pid-lock] write lock failed: ${err.message}`);
|
|
22849
22849
|
}
|
|
22850
|
-
const
|
|
22850
|
+
const release3 = () => {
|
|
22851
22851
|
try {
|
|
22852
22852
|
const cur = fs11.existsSync(lockFile) ? fs11.readFileSync(lockFile, "utf-8").trim() : "";
|
|
22853
22853
|
if (cur === String(myPid)) fs11.unlinkSync(lockFile);
|
|
22854
22854
|
} catch {
|
|
22855
22855
|
}
|
|
22856
22856
|
};
|
|
22857
|
-
process.on("exit",
|
|
22857
|
+
process.on("exit", release3);
|
|
22858
22858
|
process.on("SIGINT", () => {
|
|
22859
|
-
|
|
22859
|
+
release3();
|
|
22860
22860
|
process.exit(0);
|
|
22861
22861
|
});
|
|
22862
22862
|
process.on("SIGTERM", () => {
|
|
22863
|
-
|
|
22863
|
+
release3();
|
|
22864
22864
|
process.exit(0);
|
|
22865
22865
|
});
|
|
22866
22866
|
}
|
|
@@ -28389,10 +28389,10 @@ var US_HALF_LIFE_DAYS = 10;
|
|
|
28389
28389
|
var US_MAX_LINES = 60;
|
|
28390
28390
|
function readRecentMemory(workspace) {
|
|
28391
28391
|
const dir = path30.join(workspace, "memory");
|
|
28392
|
-
const
|
|
28392
|
+
const today2 = dailyFileKeyFor();
|
|
28393
28393
|
const yesterday = dailyFileKeyFor(Date.now() - 864e5);
|
|
28394
28394
|
return {
|
|
28395
|
-
today: readIfExists(path30.join(dir, `${
|
|
28395
|
+
today: readIfExists(path30.join(dir, `${today2}.md`)),
|
|
28396
28396
|
yesterday: readIfExists(path30.join(dir, `${yesterday}.md`))
|
|
28397
28397
|
};
|
|
28398
28398
|
}
|
|
@@ -32329,6 +32329,200 @@ ${pathStr}` }];
|
|
|
32329
32329
|
channelManager.startAll();
|
|
32330
32330
|
}
|
|
32331
32331
|
|
|
32332
|
+
// src/optional/reporting/reporter.ts
|
|
32333
|
+
init_live();
|
|
32334
|
+
|
|
32335
|
+
// src/provision-free.ts
|
|
32336
|
+
import { chmodSync, existsSync as existsSync21, mkdirSync as mkdirSync13, readFileSync as readFileSync33, writeFileSync as writeFileSync11 } from "node:fs";
|
|
32337
|
+
import { dirname as dirname9, join as join44 } from "node:path";
|
|
32338
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
32339
|
+
var __filename = fileURLToPath7(import.meta.url);
|
|
32340
|
+
var IDENTITY_FILE = "install-identity.json";
|
|
32341
|
+
function readContactEmailOf(parsed) {
|
|
32342
|
+
return typeof parsed?.contactEmail === "string" ? parsed.contactEmail.trim() : "";
|
|
32343
|
+
}
|
|
32344
|
+
function readInstallIdentity(stateDir) {
|
|
32345
|
+
try {
|
|
32346
|
+
const parsed = JSON.parse(readFileSync33(join44(stateDir, IDENTITY_FILE), "utf8"));
|
|
32347
|
+
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") return null;
|
|
32348
|
+
const email = readContactEmailOf(parsed);
|
|
32349
|
+
return {
|
|
32350
|
+
installId: parsed.installId,
|
|
32351
|
+
installSecret: parsed.installSecret,
|
|
32352
|
+
...email ? { contactEmail: email } : {}
|
|
32353
|
+
};
|
|
32354
|
+
} catch {
|
|
32355
|
+
return null;
|
|
32356
|
+
}
|
|
32357
|
+
}
|
|
32358
|
+
|
|
32359
|
+
// src/optional/reporting/state.ts
|
|
32360
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync14, readFileSync as readFileSync34, writeFileSync as writeFileSync12 } from "node:fs";
|
|
32361
|
+
import { join as join45 } from "node:path";
|
|
32362
|
+
var STATE_FILE2 = "report-state.json";
|
|
32363
|
+
function readReportState(stateDir) {
|
|
32364
|
+
try {
|
|
32365
|
+
const p = join45(stateDir, STATE_FILE2);
|
|
32366
|
+
if (!existsSync22(p)) return {};
|
|
32367
|
+
const parsed = JSON.parse(readFileSync34(p, "utf8"));
|
|
32368
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
32369
|
+
return parsed;
|
|
32370
|
+
} catch {
|
|
32371
|
+
return {};
|
|
32372
|
+
}
|
|
32373
|
+
}
|
|
32374
|
+
function writeReportState(stateDir, s) {
|
|
32375
|
+
try {
|
|
32376
|
+
mkdirSync14(stateDir, { recursive: true });
|
|
32377
|
+
writeFileSync12(join45(stateDir, STATE_FILE2), JSON.stringify(s, null, 2) + "\n");
|
|
32378
|
+
} catch {
|
|
32379
|
+
}
|
|
32380
|
+
}
|
|
32381
|
+
|
|
32382
|
+
// src/optional/reporting/payload.ts
|
|
32383
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
32384
|
+
import * as os3 from "node:os";
|
|
32385
|
+
function installKeyOf(installId, installSecret) {
|
|
32386
|
+
return createHash2("sha256").update(installId + installSecret).digest("hex").slice(0, 32);
|
|
32387
|
+
}
|
|
32388
|
+
function buildReportPayload(opts) {
|
|
32389
|
+
const p = {
|
|
32390
|
+
installId: opts.identity.installId,
|
|
32391
|
+
installKey: installKeyOf(opts.identity.installId, opts.identity.installSecret),
|
|
32392
|
+
engineVersion: opts.engineVersion,
|
|
32393
|
+
platform: process.platform,
|
|
32394
|
+
osVersion: typeof os3.release === "function" ? os3.release() : "",
|
|
32395
|
+
arch: process.arch,
|
|
32396
|
+
stateDir: opts.stateDir,
|
|
32397
|
+
startedAt: opts.startedAt,
|
|
32398
|
+
// 时钟回拨时别报个负数上去
|
|
32399
|
+
uptimeSec: Math.max(0, Math.floor((opts.now - opts.startedAt) / 1e3)),
|
|
32400
|
+
msgsToday: opts.counters.msgsToday,
|
|
32401
|
+
msgsTotal: opts.counters.msgsTotal
|
|
32402
|
+
};
|
|
32403
|
+
if (opts.identity.contactEmail) p.contactEmail = opts.identity.contactEmail;
|
|
32404
|
+
return p;
|
|
32405
|
+
}
|
|
32406
|
+
|
|
32407
|
+
// src/core/activity-counter.ts
|
|
32408
|
+
init_clock();
|
|
32409
|
+
var USER_SOURCES = /* @__PURE__ */ new Set(["user", "inbox"]);
|
|
32410
|
+
var nowFn = () => /* @__PURE__ */ new Date();
|
|
32411
|
+
var today = "";
|
|
32412
|
+
var msgsToday = 0;
|
|
32413
|
+
var msgsTotal = 0;
|
|
32414
|
+
function rolloverIfNeeded(now) {
|
|
32415
|
+
const d = todayKey(now);
|
|
32416
|
+
if (d !== today) {
|
|
32417
|
+
today = d;
|
|
32418
|
+
msgsToday = 0;
|
|
32419
|
+
}
|
|
32420
|
+
}
|
|
32421
|
+
function noteUserMessage(source) {
|
|
32422
|
+
if (!source || !USER_SOURCES.has(source)) return;
|
|
32423
|
+
const now = nowFn();
|
|
32424
|
+
rolloverIfNeeded(now);
|
|
32425
|
+
msgsToday++;
|
|
32426
|
+
msgsTotal++;
|
|
32427
|
+
}
|
|
32428
|
+
function snapshotCounters() {
|
|
32429
|
+
rolloverIfNeeded(nowFn());
|
|
32430
|
+
return { day: today, msgsToday, msgsTotal };
|
|
32431
|
+
}
|
|
32432
|
+
function restoreCounters(s) {
|
|
32433
|
+
today = todayKey(nowFn());
|
|
32434
|
+
msgsToday = s.day === today && typeof s.msgsToday === "number" && s.msgsToday > 0 ? s.msgsToday : 0;
|
|
32435
|
+
msgsTotal = typeof s.msgsTotal === "number" && s.msgsTotal > 0 ? s.msgsTotal : 0;
|
|
32436
|
+
}
|
|
32437
|
+
|
|
32438
|
+
// src/optional/reporting/reporter.ts
|
|
32439
|
+
init_api_status();
|
|
32440
|
+
var DEFAULT_REPORT_URL = "https://www.twinsun.top:8866/api/engine7/report";
|
|
32441
|
+
var DEFAULT_INTERVAL_MS2 = 5 * 60 * 1e3;
|
|
32442
|
+
var DEFAULT_INITIAL_DELAY_MS = 10 * 1e3;
|
|
32443
|
+
var FETCH_TIMEOUT_MS = 10 * 1e3;
|
|
32444
|
+
function acceptReportUrl(v) {
|
|
32445
|
+
if (typeof v !== "string") return null;
|
|
32446
|
+
const t = v.trim();
|
|
32447
|
+
return t.startsWith("https://") ? t : null;
|
|
32448
|
+
}
|
|
32449
|
+
function startReporting(opts) {
|
|
32450
|
+
const { stateDir } = opts;
|
|
32451
|
+
const doFetch = opts.fetchImpl ?? fetch;
|
|
32452
|
+
const nowFn2 = opts.now ?? (() => Date.now());
|
|
32453
|
+
const intervalMs = opts.intervalMs ?? DEFAULT_INTERVAL_MS2;
|
|
32454
|
+
const initialDelayMs = opts.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS;
|
|
32455
|
+
const log = opts.log ?? (() => {
|
|
32456
|
+
});
|
|
32457
|
+
const startedAt = nowFn2();
|
|
32458
|
+
const maybeIdentity = readInstallIdentity(stateDir);
|
|
32459
|
+
if (!maybeIdentity) {
|
|
32460
|
+
log("[reporting] \u6CA1\u6709\u53EF\u7528\u7684\u88C5\u673A\u8EAB\u4EFD\uFF0C\u4E0A\u62A5\u5173\u95ED");
|
|
32461
|
+
return { stop() {
|
|
32462
|
+
}, async beatNow() {
|
|
32463
|
+
} };
|
|
32464
|
+
}
|
|
32465
|
+
const identity = maybeIdentity;
|
|
32466
|
+
restoreCounters(readReportState(stateDir));
|
|
32467
|
+
const engineVersion = readEngineVersion();
|
|
32468
|
+
let timer = null;
|
|
32469
|
+
let stopped = false;
|
|
32470
|
+
async function beatOnce() {
|
|
32471
|
+
const state2 = readReportState(stateDir);
|
|
32472
|
+
const enabled = liveConfig.get("reporting.enabled") !== false;
|
|
32473
|
+
const counters = snapshotCounters();
|
|
32474
|
+
if (!enabled) {
|
|
32475
|
+
writeReportState(stateDir, { ...counters, reportUrl: state2.reportUrl });
|
|
32476
|
+
return;
|
|
32477
|
+
}
|
|
32478
|
+
const fromServer = acceptReportUrl(state2.reportUrl);
|
|
32479
|
+
const fromConfig = (liveConfig.get("reporting.url") || "").trim();
|
|
32480
|
+
const url = fromServer ?? (fromConfig || DEFAULT_REPORT_URL);
|
|
32481
|
+
const payload = buildReportPayload({
|
|
32482
|
+
identity,
|
|
32483
|
+
stateDir,
|
|
32484
|
+
engineVersion,
|
|
32485
|
+
startedAt,
|
|
32486
|
+
now: nowFn2(),
|
|
32487
|
+
counters
|
|
32488
|
+
});
|
|
32489
|
+
let nextUrl = state2.reportUrl;
|
|
32490
|
+
try {
|
|
32491
|
+
const res = await doFetch(url, {
|
|
32492
|
+
method: "POST",
|
|
32493
|
+
headers: { "Content-Type": "application/json" },
|
|
32494
|
+
body: JSON.stringify(payload),
|
|
32495
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
32496
|
+
});
|
|
32497
|
+
const body = JSON.parse(await res.text());
|
|
32498
|
+
const adopted = acceptReportUrl(body?.reportUrl);
|
|
32499
|
+
if (adopted) nextUrl = adopted;
|
|
32500
|
+
} catch {
|
|
32501
|
+
}
|
|
32502
|
+
writeReportState(stateDir, { ...counters, reportUrl: nextUrl });
|
|
32503
|
+
}
|
|
32504
|
+
function schedule(delay) {
|
|
32505
|
+
if (stopped) return;
|
|
32506
|
+
timer = setTimeout(() => {
|
|
32507
|
+
void beatOnce().finally(() => schedule(intervalMs));
|
|
32508
|
+
}, delay);
|
|
32509
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
32510
|
+
}
|
|
32511
|
+
schedule(initialDelayMs);
|
|
32512
|
+
return {
|
|
32513
|
+
stop() {
|
|
32514
|
+
stopped = true;
|
|
32515
|
+
if (timer) {
|
|
32516
|
+
clearTimeout(timer);
|
|
32517
|
+
timer = null;
|
|
32518
|
+
}
|
|
32519
|
+
},
|
|
32520
|
+
async beatNow() {
|
|
32521
|
+
await beatOnce();
|
|
32522
|
+
}
|
|
32523
|
+
};
|
|
32524
|
+
}
|
|
32525
|
+
|
|
32332
32526
|
// src/engine-startup.ts
|
|
32333
32527
|
init_provider_factory();
|
|
32334
32528
|
|
|
@@ -33499,7 +33693,7 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
33499
33693
|
import * as crypto4 from "crypto";
|
|
33500
33694
|
import * as fs38 from "fs";
|
|
33501
33695
|
import * as path38 from "path";
|
|
33502
|
-
import * as
|
|
33696
|
+
import * as os4 from "os";
|
|
33503
33697
|
import { promises as dns } from "dns";
|
|
33504
33698
|
function sleep3(ms) {
|
|
33505
33699
|
return new Promise((r) => setTimeout(r, ms));
|
|
@@ -33882,7 +34076,7 @@ var WechatAdapter = class {
|
|
|
33882
34076
|
this.config = config;
|
|
33883
34077
|
this.baseUrl = config.baseUrl?.replace(/\/$/, "") || ILINK_BASE_URL;
|
|
33884
34078
|
this.cdnBaseUrl = config.cdnBaseUrl?.replace(/\/$/, "") || WEIXIN_CDN_BASE_URL;
|
|
33885
|
-
this.stateDir = config.stateDir || path38.join(
|
|
34079
|
+
this.stateDir = config.stateDir || path38.join(os4.homedir?.() || "/tmp", ".engine7");
|
|
33886
34080
|
if (!fs38.existsSync(this.stateDir)) fs38.mkdirSync(this.stateDir, { recursive: true });
|
|
33887
34081
|
}
|
|
33888
34082
|
// --- ChannelAdapter interface ---
|
|
@@ -34228,7 +34422,7 @@ var WechatAdapter = class {
|
|
|
34228
34422
|
mediaRef.full_url,
|
|
34229
34423
|
timeoutSec
|
|
34230
34424
|
);
|
|
34231
|
-
const tmpDir = path38.join(
|
|
34425
|
+
const tmpDir = path38.join(os4.tmpdir(), "weixin-media");
|
|
34232
34426
|
if (!fs38.existsSync(tmpDir)) fs38.mkdirSync(tmpDir, { recursive: true });
|
|
34233
34427
|
const tmpPath = path38.join(tmpDir, `${crypto4.randomUUID().replace(/-/g, "")}-${filename}`);
|
|
34234
34428
|
fs38.writeFileSync(tmpPath, data);
|
|
@@ -34490,10 +34684,10 @@ import { createInterface as createInterface2 } from "node:readline";
|
|
|
34490
34684
|
import { promisify as promisify2 } from "node:util";
|
|
34491
34685
|
import * as fs41 from "node:fs";
|
|
34492
34686
|
import * as path40 from "node:path";
|
|
34493
|
-
import * as
|
|
34687
|
+
import * as os5 from "node:os";
|
|
34494
34688
|
import net4 from "net";
|
|
34495
34689
|
var execFileAsync2 = promisify2(execFile2);
|
|
34496
|
-
var VOICE_DIR = path40.join(
|
|
34690
|
+
var VOICE_DIR = path40.join(os5.tmpdir(), "engine-voice");
|
|
34497
34691
|
var _pyCache = null;
|
|
34498
34692
|
function resolvePython(configuredPath) {
|
|
34499
34693
|
if (configuredPath) {
|
|
@@ -35137,10 +35331,10 @@ var DeskBuddyAdapter = class {
|
|
|
35137
35331
|
appendHistory(entry) {
|
|
35138
35332
|
try {
|
|
35139
35333
|
if (!this.historyFile) {
|
|
35140
|
-
const
|
|
35334
|
+
const os6 = __require("os");
|
|
35141
35335
|
const fs57 = __require("fs");
|
|
35142
35336
|
const path58 = __require("path");
|
|
35143
|
-
const dir = path58.join(
|
|
35337
|
+
const dir = path58.join(os6.homedir(), "xiaowen", "workspace", ".desktopBuddy");
|
|
35144
35338
|
fs57.mkdirSync(dir, { recursive: true });
|
|
35145
35339
|
this.historyFile = path58.join(dir, "history.json");
|
|
35146
35340
|
this._fs = fs57;
|
|
@@ -37466,6 +37660,7 @@ var MessageDispatcher = class {
|
|
|
37466
37660
|
displayText = imgCount > 0 ? `${txt} [\u56FE\u7247\xD7${imgCount}]`.trim() : txt;
|
|
37467
37661
|
}
|
|
37468
37662
|
console.log(`[dispatcher] Executing (session=${msg2.sessionId}, source=${msg2.source}, gen=${generation}): ${displayText.slice(0, 200).replace(/\n/g, " ")}`);
|
|
37663
|
+
noteUserMessage(msg2.source);
|
|
37469
37664
|
try {
|
|
37470
37665
|
await handleQuery(
|
|
37471
37666
|
msg2.text,
|
|
@@ -40919,7 +41114,7 @@ ${err.stack}`);
|
|
|
40919
41114
|
// src/commands/model.ts
|
|
40920
41115
|
import * as fs54 from "node:fs";
|
|
40921
41116
|
import * as path54 from "node:path";
|
|
40922
|
-
import { fileURLToPath as
|
|
41117
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
40923
41118
|
function collectModels(config) {
|
|
40924
41119
|
const aliases = config.modelAliases || {};
|
|
40925
41120
|
const aliasByRef = /* @__PURE__ */ new Map();
|
|
@@ -40951,7 +41146,7 @@ function resolveConfigWritePath(config, label) {
|
|
|
40951
41146
|
if (!configPath) return void 0;
|
|
40952
41147
|
let writePath = configPath;
|
|
40953
41148
|
if (configPath && !fs54.existsSync(configPath)) {
|
|
40954
|
-
const __pFile =
|
|
41149
|
+
const __pFile = fileURLToPath8(import.meta.url);
|
|
40955
41150
|
const __pDir = path54.dirname(__pFile);
|
|
40956
41151
|
const altPath = path54.join(path54.resolve(__pDir, "../configs"), path54.basename(configPath));
|
|
40957
41152
|
if (fs54.existsSync(altPath)) {
|
|
@@ -42044,6 +42239,33 @@ async function startEngine(config, opts) {
|
|
|
42044
42239
|
// 常开 entry,stop 不触发
|
|
42045
42240
|
});
|
|
42046
42241
|
}
|
|
42242
|
+
{
|
|
42243
|
+
let reportingHandle;
|
|
42244
|
+
const stopReporting = () => {
|
|
42245
|
+
try {
|
|
42246
|
+
reportingHandle?.stop();
|
|
42247
|
+
} catch {
|
|
42248
|
+
}
|
|
42249
|
+
reportingHandle = void 0;
|
|
42250
|
+
};
|
|
42251
|
+
const startReportingNow = () => {
|
|
42252
|
+
stopReporting();
|
|
42253
|
+
reportingHandle = startReporting({ stateDir: config.stateDir });
|
|
42254
|
+
};
|
|
42255
|
+
const reportingEnabled = () => liveConfig.get("reporting.enabled") !== false;
|
|
42256
|
+
reloadOrchestrator.register({
|
|
42257
|
+
name: "reporting",
|
|
42258
|
+
// url 也进 key:运维手改地址要能热生效,不用重启
|
|
42259
|
+
select: (cfg) => ({ enabled: cfg.reporting?.enabled !== false, url: cfg.reporting?.url ?? "" }),
|
|
42260
|
+
start: async () => {
|
|
42261
|
+
startReportingNow();
|
|
42262
|
+
},
|
|
42263
|
+
stop: async () => {
|
|
42264
|
+
stopReporting();
|
|
42265
|
+
}
|
|
42266
|
+
}, reportingEnabled());
|
|
42267
|
+
if (reportingEnabled()) startReportingNow();
|
|
42268
|
+
}
|
|
42047
42269
|
const shutdownPromise = new Promise((resolve12) => {
|
|
42048
42270
|
const shutdown = (signal) => {
|
|
42049
42271
|
console.log(`[engine] ${signal} received, shutting down...`);
|
package/dist/main.mjs
CHANGED
|
@@ -8215,26 +8215,26 @@ async function writeToMailbox(recipientName, message, teamName) {
|
|
|
8215
8215
|
await writeFile2(inboxPath, "[]", { encoding: "utf-8", flag: "wx" });
|
|
8216
8216
|
} catch {
|
|
8217
8217
|
}
|
|
8218
|
-
const
|
|
8218
|
+
const release3 = await acquireLock(inboxPath);
|
|
8219
8219
|
try {
|
|
8220
8220
|
const messages = await readMailbox(recipientName, teamName);
|
|
8221
8221
|
messages.push({ ...message, read: false });
|
|
8222
8222
|
await writeFile2(inboxPath, JSON.stringify(messages, null, 2), "utf-8");
|
|
8223
8223
|
console.log(`[mailbox] Wrote message to ${recipientName} from ${message.from} (team=${teamName || "default"}, inbox=${inboxPath})`);
|
|
8224
8224
|
} finally {
|
|
8225
|
-
await
|
|
8225
|
+
await release3();
|
|
8226
8226
|
}
|
|
8227
8227
|
}
|
|
8228
8228
|
async function markMessagesAsRead(agentName, teamName) {
|
|
8229
8229
|
const inboxPath = getInboxPath(agentName, teamName);
|
|
8230
|
-
const
|
|
8230
|
+
const release3 = await acquireLock(inboxPath);
|
|
8231
8231
|
try {
|
|
8232
8232
|
const messages = await readMailbox(agentName, teamName);
|
|
8233
8233
|
if (messages.length === 0) return;
|
|
8234
8234
|
for (const m of messages) m.read = true;
|
|
8235
8235
|
await writeFile2(inboxPath, JSON.stringify(messages, null, 2), "utf-8");
|
|
8236
8236
|
} finally {
|
|
8237
|
-
await
|
|
8237
|
+
await release3();
|
|
8238
8238
|
}
|
|
8239
8239
|
}
|
|
8240
8240
|
async function clearMailbox(agentName, teamName) {
|
|
@@ -10065,7 +10065,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10065
10065
|
}
|
|
10066
10066
|
// ── md 读(proactive 消费):开窗预测(全 owner 扫描,end>=今天)──
|
|
10067
10067
|
getOpenPredictions(now, limit = 50) {
|
|
10068
|
-
const
|
|
10068
|
+
const today2 = todayKey(now);
|
|
10069
10069
|
const out = [];
|
|
10070
10070
|
const usersDir = join23(this.root, "users");
|
|
10071
10071
|
if (!existsSync13(usersDir)) return out;
|
|
@@ -10088,7 +10088,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10088
10088
|
const text = ((block.match(/### Foresight\s*\n+([\s\S]*?)(?:\n### Evidence|$)/) ?? [])[1] ?? "").trim();
|
|
10089
10089
|
const evidence = ((block.match(/### Evidence\s*\n+([\s\S]*?)$/) ?? [])[1] ?? "").trim();
|
|
10090
10090
|
if (!end || !start || !text) continue;
|
|
10091
|
-
if (end <
|
|
10091
|
+
if (end < today2) continue;
|
|
10092
10092
|
out.push({ ownerId: owner.name, startDate: start, endDate: end, content: text.replace(/\n+/g, " ").slice(0, 200), evidence: evidence.replace(/\n+/g, " ").slice(0, 120) });
|
|
10093
10093
|
if (out.length >= limit) return out;
|
|
10094
10094
|
}
|
|
@@ -13629,7 +13629,7 @@ function loadForesightEntries(everosRoot, now, userId, ownerFilter) {
|
|
|
13629
13629
|
return entries2.slice();
|
|
13630
13630
|
}
|
|
13631
13631
|
function parseForesightEntries(everosRoot, now, userId) {
|
|
13632
|
-
const
|
|
13632
|
+
const today2 = todayKey(now);
|
|
13633
13633
|
let files;
|
|
13634
13634
|
if (userId) {
|
|
13635
13635
|
const ownDir = join30(everosRoot, userId, "default_project", "users", userId, ".foresights");
|
|
@@ -13654,7 +13654,7 @@ function parseForesightEntries(everosRoot, now, userId) {
|
|
|
13654
13654
|
const end = (block.match(/\*\*end_time\*\*:\s*(\d{4}-\d{2}-\d{2})/) ?? [])[1];
|
|
13655
13655
|
const text = ((block.match(/### Foresight\s*\n+([\s\S]*?)(?:\n### Evidence|$)/) ?? [])[1] ?? "").trim();
|
|
13656
13656
|
if (!start || !end || !text) continue;
|
|
13657
|
-
if (end <
|
|
13657
|
+
if (end < today2) continue;
|
|
13658
13658
|
const evidence = ((block.match(/### Evidence\s*\n+([\s\S]*?)$/) ?? [])[1] ?? "").trim();
|
|
13659
13659
|
const blockOwner = (block.match(/\*\*owner_id\*\*:\s*(\S+)/) ?? [])[1] ?? fileOwner;
|
|
13660
13660
|
const key = text.replace(/\s+/g, "");
|
|
@@ -21592,7 +21592,7 @@ function isPermittedRedirect(original, redirect) {
|
|
|
21592
21592
|
async function fetchWithRedirects(url, signal, depth = 0) {
|
|
21593
21593
|
if (depth > MAX_REDIRECTS) throw new Error(`\u91CD\u5B9A\u5411\u6B21\u6570\u8FC7\u591A (>${MAX_REDIRECTS})`);
|
|
21594
21594
|
const controller = new AbortController();
|
|
21595
|
-
const timeoutId = setTimeout(() => controller.abort(),
|
|
21595
|
+
const timeoutId = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS2);
|
|
21596
21596
|
const onSignalAbort = () => controller.abort();
|
|
21597
21597
|
signal.addEventListener("abort", onSignalAbort, { once: true });
|
|
21598
21598
|
try {
|
|
@@ -21635,14 +21635,14 @@ function getTurndown() {
|
|
|
21635
21635
|
}
|
|
21636
21636
|
return td;
|
|
21637
21637
|
}
|
|
21638
|
-
var MAX_URL_LENGTH, MAX_CONTENT_LENGTH,
|
|
21638
|
+
var MAX_URL_LENGTH, MAX_CONTENT_LENGTH, FETCH_TIMEOUT_MS2, MAX_REDIRECTS, td;
|
|
21639
21639
|
var init_web_fetch = __esm({
|
|
21640
21640
|
"src/tools/web-fetch.ts"() {
|
|
21641
21641
|
"use strict";
|
|
21642
21642
|
init_registry();
|
|
21643
21643
|
MAX_URL_LENGTH = 2e3;
|
|
21644
21644
|
MAX_CONTENT_LENGTH = 10 * 1024 * 1024;
|
|
21645
|
-
|
|
21645
|
+
FETCH_TIMEOUT_MS2 = 6e4;
|
|
21646
21646
|
MAX_REDIRECTS = 10;
|
|
21647
21647
|
registry.register({
|
|
21648
21648
|
name: "web_fetch",
|
|
@@ -21713,7 +21713,7 @@ var init_web_fetch = __esm({
|
|
|
21713
21713
|
|
|
21714
21714
|
// src/tools/wechat/wx-query.ts
|
|
21715
21715
|
var wx_query_exports = {};
|
|
21716
|
-
import { join as
|
|
21716
|
+
import { join as join57 } from "node:path";
|
|
21717
21717
|
function getDescription() {
|
|
21718
21718
|
return `\u67E5\u8BE2\u7FC0\u54E5\u7684\u5FAE\u4FE1\u6D88\u606F\uFF08\u7F13\u5B58\u89E3\u5BC6\u540E\u7684\u672C\u5730\u6570\u636E\u5E93\uFF09\u3002
|
|
21719
21719
|
|
|
@@ -21748,8 +21748,8 @@ var init_wx_query = __esm({
|
|
|
21748
21748
|
"use strict";
|
|
21749
21749
|
init_registry();
|
|
21750
21750
|
init_live();
|
|
21751
|
-
STATE_DIR = process.env.ENGINE7_STATE_DIR ||
|
|
21752
|
-
SCRIPT =
|
|
21751
|
+
STATE_DIR = process.env.ENGINE7_STATE_DIR || join57(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
|
|
21752
|
+
SCRIPT = join57("/Users/chongzhang/work/twinsun-hearth/engine", "src", "tools", "wechat", "wx_query.py");
|
|
21753
21753
|
PYTHON = "python3";
|
|
21754
21754
|
registry.register({
|
|
21755
21755
|
name: "wx_query",
|
|
@@ -22924,8 +22924,8 @@ async function doReloadConfigInner(config2, deps, provider, force = false) {
|
|
|
22924
22924
|
const savedConfigPath = config2._configFilePath;
|
|
22925
22925
|
let reloadConfigPath = savedConfigPath;
|
|
22926
22926
|
if (!fs10.existsSync(reloadConfigPath)) {
|
|
22927
|
-
const
|
|
22928
|
-
const __dirname = path10.dirname(
|
|
22927
|
+
const __filename2 = fileURLToPath(import.meta.url);
|
|
22928
|
+
const __dirname = path10.dirname(__filename2);
|
|
22929
22929
|
const engineConfigsDir = path10.resolve(__dirname, "../configs");
|
|
22930
22930
|
const altPath = path10.join(engineConfigsDir, path10.basename(savedConfigPath));
|
|
22931
22931
|
if (fs10.existsSync(altPath)) {
|
|
@@ -23239,20 +23239,20 @@ function acquireEngineLock(stateDir) {
|
|
|
23239
23239
|
} catch (err) {
|
|
23240
23240
|
console.warn(`[pid-lock] write lock failed: ${err.message}`);
|
|
23241
23241
|
}
|
|
23242
|
-
const
|
|
23242
|
+
const release3 = () => {
|
|
23243
23243
|
try {
|
|
23244
23244
|
const cur = fs11.existsSync(lockFile) ? fs11.readFileSync(lockFile, "utf-8").trim() : "";
|
|
23245
23245
|
if (cur === String(myPid)) fs11.unlinkSync(lockFile);
|
|
23246
23246
|
} catch {
|
|
23247
23247
|
}
|
|
23248
23248
|
};
|
|
23249
|
-
process.on("exit",
|
|
23249
|
+
process.on("exit", release3);
|
|
23250
23250
|
process.on("SIGINT", () => {
|
|
23251
|
-
|
|
23251
|
+
release3();
|
|
23252
23252
|
process.exit(0);
|
|
23253
23253
|
});
|
|
23254
23254
|
process.on("SIGTERM", () => {
|
|
23255
|
-
|
|
23255
|
+
release3();
|
|
23256
23256
|
process.exit(0);
|
|
23257
23257
|
});
|
|
23258
23258
|
}
|
|
@@ -28686,10 +28686,10 @@ var US_HALF_LIFE_DAYS = 10;
|
|
|
28686
28686
|
var US_MAX_LINES = 60;
|
|
28687
28687
|
function readRecentMemory(workspace) {
|
|
28688
28688
|
const dir = path30.join(workspace, "memory");
|
|
28689
|
-
const
|
|
28689
|
+
const today2 = dailyFileKeyFor();
|
|
28690
28690
|
const yesterday = dailyFileKeyFor(Date.now() - 864e5);
|
|
28691
28691
|
return {
|
|
28692
|
-
today: readIfExists(path30.join(dir, `${
|
|
28692
|
+
today: readIfExists(path30.join(dir, `${today2}.md`)),
|
|
28693
28693
|
yesterday: readIfExists(path30.join(dir, `${yesterday}.md`))
|
|
28694
28694
|
};
|
|
28695
28695
|
}
|
|
@@ -32626,6 +32626,200 @@ ${pathStr}` }];
|
|
|
32626
32626
|
channelManager.startAll();
|
|
32627
32627
|
}
|
|
32628
32628
|
|
|
32629
|
+
// src/optional/reporting/reporter.ts
|
|
32630
|
+
init_live();
|
|
32631
|
+
|
|
32632
|
+
// src/provision-free.ts
|
|
32633
|
+
import { chmodSync as chmodSync2, existsSync as existsSync22, mkdirSync as mkdirSync14, readFileSync as readFileSync34, writeFileSync as writeFileSync12 } from "node:fs";
|
|
32634
|
+
import { dirname as dirname10, join as join45 } from "node:path";
|
|
32635
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
32636
|
+
var __filename = fileURLToPath7(import.meta.url);
|
|
32637
|
+
var IDENTITY_FILE = "install-identity.json";
|
|
32638
|
+
function readContactEmailOf(parsed) {
|
|
32639
|
+
return typeof parsed?.contactEmail === "string" ? parsed.contactEmail.trim() : "";
|
|
32640
|
+
}
|
|
32641
|
+
function readInstallIdentity(stateDir) {
|
|
32642
|
+
try {
|
|
32643
|
+
const parsed = JSON.parse(readFileSync34(join45(stateDir, IDENTITY_FILE), "utf8"));
|
|
32644
|
+
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") return null;
|
|
32645
|
+
const email = readContactEmailOf(parsed);
|
|
32646
|
+
return {
|
|
32647
|
+
installId: parsed.installId,
|
|
32648
|
+
installSecret: parsed.installSecret,
|
|
32649
|
+
...email ? { contactEmail: email } : {}
|
|
32650
|
+
};
|
|
32651
|
+
} catch {
|
|
32652
|
+
return null;
|
|
32653
|
+
}
|
|
32654
|
+
}
|
|
32655
|
+
|
|
32656
|
+
// src/optional/reporting/state.ts
|
|
32657
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync15, readFileSync as readFileSync35, writeFileSync as writeFileSync13 } from "node:fs";
|
|
32658
|
+
import { join as join46 } from "node:path";
|
|
32659
|
+
var STATE_FILE2 = "report-state.json";
|
|
32660
|
+
function readReportState(stateDir) {
|
|
32661
|
+
try {
|
|
32662
|
+
const p = join46(stateDir, STATE_FILE2);
|
|
32663
|
+
if (!existsSync23(p)) return {};
|
|
32664
|
+
const parsed = JSON.parse(readFileSync35(p, "utf8"));
|
|
32665
|
+
if (!parsed || typeof parsed !== "object") return {};
|
|
32666
|
+
return parsed;
|
|
32667
|
+
} catch {
|
|
32668
|
+
return {};
|
|
32669
|
+
}
|
|
32670
|
+
}
|
|
32671
|
+
function writeReportState(stateDir, s) {
|
|
32672
|
+
try {
|
|
32673
|
+
mkdirSync15(stateDir, { recursive: true });
|
|
32674
|
+
writeFileSync13(join46(stateDir, STATE_FILE2), JSON.stringify(s, null, 2) + "\n");
|
|
32675
|
+
} catch {
|
|
32676
|
+
}
|
|
32677
|
+
}
|
|
32678
|
+
|
|
32679
|
+
// src/optional/reporting/payload.ts
|
|
32680
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
32681
|
+
import * as os3 from "node:os";
|
|
32682
|
+
function installKeyOf(installId, installSecret) {
|
|
32683
|
+
return createHash2("sha256").update(installId + installSecret).digest("hex").slice(0, 32);
|
|
32684
|
+
}
|
|
32685
|
+
function buildReportPayload(opts) {
|
|
32686
|
+
const p = {
|
|
32687
|
+
installId: opts.identity.installId,
|
|
32688
|
+
installKey: installKeyOf(opts.identity.installId, opts.identity.installSecret),
|
|
32689
|
+
engineVersion: opts.engineVersion,
|
|
32690
|
+
platform: process.platform,
|
|
32691
|
+
osVersion: typeof os3.release === "function" ? os3.release() : "",
|
|
32692
|
+
arch: process.arch,
|
|
32693
|
+
stateDir: opts.stateDir,
|
|
32694
|
+
startedAt: opts.startedAt,
|
|
32695
|
+
// 时钟回拨时别报个负数上去
|
|
32696
|
+
uptimeSec: Math.max(0, Math.floor((opts.now - opts.startedAt) / 1e3)),
|
|
32697
|
+
msgsToday: opts.counters.msgsToday,
|
|
32698
|
+
msgsTotal: opts.counters.msgsTotal
|
|
32699
|
+
};
|
|
32700
|
+
if (opts.identity.contactEmail) p.contactEmail = opts.identity.contactEmail;
|
|
32701
|
+
return p;
|
|
32702
|
+
}
|
|
32703
|
+
|
|
32704
|
+
// src/core/activity-counter.ts
|
|
32705
|
+
init_clock();
|
|
32706
|
+
var USER_SOURCES = /* @__PURE__ */ new Set(["user", "inbox"]);
|
|
32707
|
+
var nowFn = () => /* @__PURE__ */ new Date();
|
|
32708
|
+
var today = "";
|
|
32709
|
+
var msgsToday = 0;
|
|
32710
|
+
var msgsTotal = 0;
|
|
32711
|
+
function rolloverIfNeeded(now) {
|
|
32712
|
+
const d = todayKey(now);
|
|
32713
|
+
if (d !== today) {
|
|
32714
|
+
today = d;
|
|
32715
|
+
msgsToday = 0;
|
|
32716
|
+
}
|
|
32717
|
+
}
|
|
32718
|
+
function noteUserMessage(source) {
|
|
32719
|
+
if (!source || !USER_SOURCES.has(source)) return;
|
|
32720
|
+
const now = nowFn();
|
|
32721
|
+
rolloverIfNeeded(now);
|
|
32722
|
+
msgsToday++;
|
|
32723
|
+
msgsTotal++;
|
|
32724
|
+
}
|
|
32725
|
+
function snapshotCounters() {
|
|
32726
|
+
rolloverIfNeeded(nowFn());
|
|
32727
|
+
return { day: today, msgsToday, msgsTotal };
|
|
32728
|
+
}
|
|
32729
|
+
function restoreCounters(s) {
|
|
32730
|
+
today = todayKey(nowFn());
|
|
32731
|
+
msgsToday = s.day === today && typeof s.msgsToday === "number" && s.msgsToday > 0 ? s.msgsToday : 0;
|
|
32732
|
+
msgsTotal = typeof s.msgsTotal === "number" && s.msgsTotal > 0 ? s.msgsTotal : 0;
|
|
32733
|
+
}
|
|
32734
|
+
|
|
32735
|
+
// src/optional/reporting/reporter.ts
|
|
32736
|
+
init_api_status();
|
|
32737
|
+
var DEFAULT_REPORT_URL = "https://www.twinsun.top:8866/api/engine7/report";
|
|
32738
|
+
var DEFAULT_INTERVAL_MS2 = 5 * 60 * 1e3;
|
|
32739
|
+
var DEFAULT_INITIAL_DELAY_MS = 10 * 1e3;
|
|
32740
|
+
var FETCH_TIMEOUT_MS = 10 * 1e3;
|
|
32741
|
+
function acceptReportUrl(v) {
|
|
32742
|
+
if (typeof v !== "string") return null;
|
|
32743
|
+
const t = v.trim();
|
|
32744
|
+
return t.startsWith("https://") ? t : null;
|
|
32745
|
+
}
|
|
32746
|
+
function startReporting(opts) {
|
|
32747
|
+
const { stateDir } = opts;
|
|
32748
|
+
const doFetch = opts.fetchImpl ?? fetch;
|
|
32749
|
+
const nowFn2 = opts.now ?? (() => Date.now());
|
|
32750
|
+
const intervalMs = opts.intervalMs ?? DEFAULT_INTERVAL_MS2;
|
|
32751
|
+
const initialDelayMs = opts.initialDelayMs ?? DEFAULT_INITIAL_DELAY_MS;
|
|
32752
|
+
const log = opts.log ?? (() => {
|
|
32753
|
+
});
|
|
32754
|
+
const startedAt = nowFn2();
|
|
32755
|
+
const maybeIdentity = readInstallIdentity(stateDir);
|
|
32756
|
+
if (!maybeIdentity) {
|
|
32757
|
+
log("[reporting] \u6CA1\u6709\u53EF\u7528\u7684\u88C5\u673A\u8EAB\u4EFD\uFF0C\u4E0A\u62A5\u5173\u95ED");
|
|
32758
|
+
return { stop() {
|
|
32759
|
+
}, async beatNow() {
|
|
32760
|
+
} };
|
|
32761
|
+
}
|
|
32762
|
+
const identity = maybeIdentity;
|
|
32763
|
+
restoreCounters(readReportState(stateDir));
|
|
32764
|
+
const engineVersion = readEngineVersion();
|
|
32765
|
+
let timer = null;
|
|
32766
|
+
let stopped = false;
|
|
32767
|
+
async function beatOnce() {
|
|
32768
|
+
const state2 = readReportState(stateDir);
|
|
32769
|
+
const enabled = liveConfig.get("reporting.enabled") !== false;
|
|
32770
|
+
const counters = snapshotCounters();
|
|
32771
|
+
if (!enabled) {
|
|
32772
|
+
writeReportState(stateDir, { ...counters, reportUrl: state2.reportUrl });
|
|
32773
|
+
return;
|
|
32774
|
+
}
|
|
32775
|
+
const fromServer = acceptReportUrl(state2.reportUrl);
|
|
32776
|
+
const fromConfig = (liveConfig.get("reporting.url") || "").trim();
|
|
32777
|
+
const url = fromServer ?? (fromConfig || DEFAULT_REPORT_URL);
|
|
32778
|
+
const payload = buildReportPayload({
|
|
32779
|
+
identity,
|
|
32780
|
+
stateDir,
|
|
32781
|
+
engineVersion,
|
|
32782
|
+
startedAt,
|
|
32783
|
+
now: nowFn2(),
|
|
32784
|
+
counters
|
|
32785
|
+
});
|
|
32786
|
+
let nextUrl = state2.reportUrl;
|
|
32787
|
+
try {
|
|
32788
|
+
const res = await doFetch(url, {
|
|
32789
|
+
method: "POST",
|
|
32790
|
+
headers: { "Content-Type": "application/json" },
|
|
32791
|
+
body: JSON.stringify(payload),
|
|
32792
|
+
signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
|
|
32793
|
+
});
|
|
32794
|
+
const body = JSON.parse(await res.text());
|
|
32795
|
+
const adopted = acceptReportUrl(body?.reportUrl);
|
|
32796
|
+
if (adopted) nextUrl = adopted;
|
|
32797
|
+
} catch {
|
|
32798
|
+
}
|
|
32799
|
+
writeReportState(stateDir, { ...counters, reportUrl: nextUrl });
|
|
32800
|
+
}
|
|
32801
|
+
function schedule(delay) {
|
|
32802
|
+
if (stopped) return;
|
|
32803
|
+
timer = setTimeout(() => {
|
|
32804
|
+
void beatOnce().finally(() => schedule(intervalMs));
|
|
32805
|
+
}, delay);
|
|
32806
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
32807
|
+
}
|
|
32808
|
+
schedule(initialDelayMs);
|
|
32809
|
+
return {
|
|
32810
|
+
stop() {
|
|
32811
|
+
stopped = true;
|
|
32812
|
+
if (timer) {
|
|
32813
|
+
clearTimeout(timer);
|
|
32814
|
+
timer = null;
|
|
32815
|
+
}
|
|
32816
|
+
},
|
|
32817
|
+
async beatNow() {
|
|
32818
|
+
await beatOnce();
|
|
32819
|
+
}
|
|
32820
|
+
};
|
|
32821
|
+
}
|
|
32822
|
+
|
|
32629
32823
|
// src/engine-startup.ts
|
|
32630
32824
|
init_provider_factory();
|
|
32631
32825
|
|
|
@@ -33796,7 +33990,7 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
33796
33990
|
import * as crypto4 from "crypto";
|
|
33797
33991
|
import * as fs38 from "fs";
|
|
33798
33992
|
import * as path38 from "path";
|
|
33799
|
-
import * as
|
|
33993
|
+
import * as os4 from "os";
|
|
33800
33994
|
import { promises as dns } from "dns";
|
|
33801
33995
|
function sleep3(ms) {
|
|
33802
33996
|
return new Promise((r) => setTimeout(r, ms));
|
|
@@ -34179,7 +34373,7 @@ var WechatAdapter = class {
|
|
|
34179
34373
|
this.config = config2;
|
|
34180
34374
|
this.baseUrl = config2.baseUrl?.replace(/\/$/, "") || ILINK_BASE_URL;
|
|
34181
34375
|
this.cdnBaseUrl = config2.cdnBaseUrl?.replace(/\/$/, "") || WEIXIN_CDN_BASE_URL;
|
|
34182
|
-
this.stateDir = config2.stateDir || path38.join(
|
|
34376
|
+
this.stateDir = config2.stateDir || path38.join(os4.homedir?.() || "/tmp", ".engine7");
|
|
34183
34377
|
if (!fs38.existsSync(this.stateDir)) fs38.mkdirSync(this.stateDir, { recursive: true });
|
|
34184
34378
|
}
|
|
34185
34379
|
// --- ChannelAdapter interface ---
|
|
@@ -34525,7 +34719,7 @@ var WechatAdapter = class {
|
|
|
34525
34719
|
mediaRef.full_url,
|
|
34526
34720
|
timeoutSec
|
|
34527
34721
|
);
|
|
34528
|
-
const tmpDir = path38.join(
|
|
34722
|
+
const tmpDir = path38.join(os4.tmpdir(), "weixin-media");
|
|
34529
34723
|
if (!fs38.existsSync(tmpDir)) fs38.mkdirSync(tmpDir, { recursive: true });
|
|
34530
34724
|
const tmpPath = path38.join(tmpDir, `${crypto4.randomUUID().replace(/-/g, "")}-${filename}`);
|
|
34531
34725
|
fs38.writeFileSync(tmpPath, data);
|
|
@@ -34787,10 +34981,10 @@ import { createInterface as createInterface2 } from "node:readline";
|
|
|
34787
34981
|
import { promisify as promisify2 } from "node:util";
|
|
34788
34982
|
import * as fs41 from "node:fs";
|
|
34789
34983
|
import * as path40 from "node:path";
|
|
34790
|
-
import * as
|
|
34984
|
+
import * as os5 from "node:os";
|
|
34791
34985
|
import net4 from "net";
|
|
34792
34986
|
var execFileAsync2 = promisify2(execFile2);
|
|
34793
|
-
var VOICE_DIR = path40.join(
|
|
34987
|
+
var VOICE_DIR = path40.join(os5.tmpdir(), "engine-voice");
|
|
34794
34988
|
var _pyCache = null;
|
|
34795
34989
|
function resolvePython(configuredPath) {
|
|
34796
34990
|
if (configuredPath) {
|
|
@@ -35434,10 +35628,10 @@ var DeskBuddyAdapter = class {
|
|
|
35434
35628
|
appendHistory(entry) {
|
|
35435
35629
|
try {
|
|
35436
35630
|
if (!this.historyFile) {
|
|
35437
|
-
const
|
|
35631
|
+
const os6 = __require("os");
|
|
35438
35632
|
const fs57 = __require("fs");
|
|
35439
35633
|
const path58 = __require("path");
|
|
35440
|
-
const dir = path58.join(
|
|
35634
|
+
const dir = path58.join(os6.homedir(), "xiaowen", "workspace", ".desktopBuddy");
|
|
35441
35635
|
fs57.mkdirSync(dir, { recursive: true });
|
|
35442
35636
|
this.historyFile = path58.join(dir, "history.json");
|
|
35443
35637
|
this._fs = fs57;
|
|
@@ -37763,6 +37957,7 @@ var MessageDispatcher = class {
|
|
|
37763
37957
|
displayText = imgCount > 0 ? `${txt} [\u56FE\u7247\xD7${imgCount}]`.trim() : txt;
|
|
37764
37958
|
}
|
|
37765
37959
|
console.log(`[dispatcher] Executing (session=${msg2.sessionId}, source=${msg2.source}, gen=${generation}): ${displayText.slice(0, 200).replace(/\n/g, " ")}`);
|
|
37960
|
+
noteUserMessage(msg2.source);
|
|
37766
37961
|
try {
|
|
37767
37962
|
await handleQuery(
|
|
37768
37963
|
msg2.text,
|
|
@@ -41039,7 +41234,7 @@ ${err.stack}`);
|
|
|
41039
41234
|
// src/commands/model.ts
|
|
41040
41235
|
import * as fs54 from "node:fs";
|
|
41041
41236
|
import * as path54 from "node:path";
|
|
41042
|
-
import { fileURLToPath as
|
|
41237
|
+
import { fileURLToPath as fileURLToPath8 } from "node:url";
|
|
41043
41238
|
function collectModels(config2) {
|
|
41044
41239
|
const aliases = config2.modelAliases || {};
|
|
41045
41240
|
const aliasByRef = /* @__PURE__ */ new Map();
|
|
@@ -41071,7 +41266,7 @@ function resolveConfigWritePath(config2, label) {
|
|
|
41071
41266
|
if (!configPath2) return void 0;
|
|
41072
41267
|
let writePath = configPath2;
|
|
41073
41268
|
if (configPath2 && !fs54.existsSync(configPath2)) {
|
|
41074
|
-
const __pFile =
|
|
41269
|
+
const __pFile = fileURLToPath8(import.meta.url);
|
|
41075
41270
|
const __pDir = path54.dirname(__pFile);
|
|
41076
41271
|
const altPath = path54.join(path54.resolve(__pDir, "../configs"), path54.basename(configPath2));
|
|
41077
41272
|
if (fs54.existsSync(altPath)) {
|
|
@@ -42164,6 +42359,33 @@ async function startEngine(config2, opts) {
|
|
|
42164
42359
|
// 常开 entry,stop 不触发
|
|
42165
42360
|
});
|
|
42166
42361
|
}
|
|
42362
|
+
{
|
|
42363
|
+
let reportingHandle;
|
|
42364
|
+
const stopReporting = () => {
|
|
42365
|
+
try {
|
|
42366
|
+
reportingHandle?.stop();
|
|
42367
|
+
} catch {
|
|
42368
|
+
}
|
|
42369
|
+
reportingHandle = void 0;
|
|
42370
|
+
};
|
|
42371
|
+
const startReportingNow = () => {
|
|
42372
|
+
stopReporting();
|
|
42373
|
+
reportingHandle = startReporting({ stateDir: config2.stateDir });
|
|
42374
|
+
};
|
|
42375
|
+
const reportingEnabled = () => liveConfig.get("reporting.enabled") !== false;
|
|
42376
|
+
reloadOrchestrator.register({
|
|
42377
|
+
name: "reporting",
|
|
42378
|
+
// url 也进 key:运维手改地址要能热生效,不用重启
|
|
42379
|
+
select: (cfg) => ({ enabled: cfg.reporting?.enabled !== false, url: cfg.reporting?.url ?? "" }),
|
|
42380
|
+
start: async () => {
|
|
42381
|
+
startReportingNow();
|
|
42382
|
+
},
|
|
42383
|
+
stop: async () => {
|
|
42384
|
+
stopReporting();
|
|
42385
|
+
}
|
|
42386
|
+
}, reportingEnabled());
|
|
42387
|
+
if (reportingEnabled()) startReportingNow();
|
|
42388
|
+
}
|
|
42167
42389
|
const shutdownPromise = new Promise((resolve12) => {
|
|
42168
42390
|
const shutdown = (signal) => {
|
|
42169
42391
|
console.log(`[engine] ${signal} received, shutting down...`);
|
|
@@ -42206,11 +42428,11 @@ async function startEngine(config2, opts) {
|
|
|
42206
42428
|
}
|
|
42207
42429
|
|
|
42208
42430
|
// src/main.ts
|
|
42209
|
-
import { readFileSync as
|
|
42210
|
-
import { fileURLToPath as
|
|
42211
|
-
import { dirname as
|
|
42212
|
-
var __dirname2 =
|
|
42213
|
-
var pkg = JSON.parse(
|
|
42431
|
+
import { readFileSync as readFileSync47 } from "node:fs";
|
|
42432
|
+
import { fileURLToPath as fileURLToPath9 } from "node:url";
|
|
42433
|
+
import { dirname as dirname16, join as join63 } from "node:path";
|
|
42434
|
+
var __dirname2 = dirname16(fileURLToPath9(import.meta.url));
|
|
42435
|
+
var pkg = JSON.parse(readFileSync47(join63(__dirname2, "..", "package.json"), "utf-8"));
|
|
42214
42436
|
var epipeSeen = false;
|
|
42215
42437
|
process.on("uncaughtException", (err) => {
|
|
42216
42438
|
const code = err?.code ?? "";
|