engine7 7.1.118 → 7.1.120
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 +1054 -891
- package/dist/engine-startup.mjs +394 -275
- package/dist/main.mjs +394 -275
- package/package.json +3 -3
package/dist/engine-startup.mjs
CHANGED
|
@@ -2429,6 +2429,17 @@ var init_live = __esm({
|
|
|
2429
2429
|
Object.assign(this.current, newConfig);
|
|
2430
2430
|
}
|
|
2431
2431
|
/** 改活树上的值;文件承载路径同步持久化(read-modify-write 回 config 文件) */
|
|
2432
|
+
/**
|
|
2433
|
+
* 改活树 + 落盘。
|
|
2434
|
+
*
|
|
2435
|
+
* 返回值 = **落盘**是否成功(活树无论成败都已同步——它是先改的)。绝大多数调用点照旧
|
|
2436
|
+
* `void liveConfig.set(...)` 不理它;但**要打成功日志的调用点必须 await 这个布尔值**。
|
|
2437
|
+
*
|
|
2438
|
+
* 为什么把这个信号交出去(1001 审查捞回):本方法本来是 fire-and-forget,落盘失败只在
|
|
2439
|
+
* `persistToFile` 里 warn 一行;而启动早段的调用点(两个免费档 fixup)紧接着打了句
|
|
2440
|
+
* "免费档补齐 xxx" 的成功日志 ⇒ 配置**没写进文件**却被读成"写好了":进程内生效、托盘
|
|
2441
|
+
* 读文件还是旧值、下次启动重放同一句——正是本仓最恨的假信号。
|
|
2442
|
+
*/
|
|
2432
2443
|
async set(dotPath, val) {
|
|
2433
2444
|
if (!this.current) throw new Error("[liveConfig] not initialized \u2014 call liveConfig.init() first");
|
|
2434
2445
|
const keys = dotPath.split(".");
|
|
@@ -2438,15 +2449,15 @@ var init_live = __esm({
|
|
|
2438
2449
|
obj = obj[keys[i]];
|
|
2439
2450
|
}
|
|
2440
2451
|
obj[keys[keys.length - 1]] = val;
|
|
2441
|
-
|
|
2452
|
+
return this.persistToFile(dotPath, val);
|
|
2442
2453
|
}
|
|
2443
|
-
/** 把改动写回 config
|
|
2454
|
+
/** 把改动写回 config 文件对应段(找不到文件路径则只内存生效)。返回是否真的落盘。 */
|
|
2444
2455
|
async persistToFile(dotPath, val) {
|
|
2445
2456
|
const fs60 = await import("node:fs");
|
|
2446
2457
|
const cfgPath = this.current?._configFilePath;
|
|
2447
2458
|
if (!cfgPath || !fs60.existsSync(cfgPath)) {
|
|
2448
2459
|
console.warn(`[liveConfig] set: no config file path, in-memory only (${dotPath})`);
|
|
2449
|
-
return;
|
|
2460
|
+
return false;
|
|
2450
2461
|
}
|
|
2451
2462
|
try {
|
|
2452
2463
|
const raw = JSON.parse(fs60.readFileSync(cfgPath, "utf-8"));
|
|
@@ -2460,8 +2471,10 @@ var init_live = __esm({
|
|
|
2460
2471
|
fs60.writeFileSync(cfgPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
|
|
2461
2472
|
console.log(`[liveConfig] persisted ${dotPath} = ${JSON.stringify(val)} to ${cfgPath}`);
|
|
2462
2473
|
markSelfWrite();
|
|
2474
|
+
return true;
|
|
2463
2475
|
} catch (e) {
|
|
2464
2476
|
console.warn(`[liveConfig] persist failed (${dotPath}): ${e.message}`);
|
|
2477
|
+
return false;
|
|
2465
2478
|
}
|
|
2466
2479
|
}
|
|
2467
2480
|
/** 是否已初始化 */
|
|
@@ -8176,30 +8189,30 @@ __export(teamHelpers_exports, {
|
|
|
8176
8189
|
writeTeamFile: () => writeTeamFile,
|
|
8177
8190
|
writeTeamFileAsync: () => writeTeamFileAsync
|
|
8178
8191
|
});
|
|
8179
|
-
import { mkdirSync as
|
|
8192
|
+
import { mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync5 } from "node:fs";
|
|
8180
8193
|
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
8181
|
-
import { join as
|
|
8194
|
+
import { join as join17 } from "node:path";
|
|
8182
8195
|
function initTeamDirs(stateDir) {
|
|
8183
8196
|
_stateDir = stateDir;
|
|
8184
8197
|
}
|
|
8185
8198
|
function getTeamsDir() {
|
|
8186
|
-
return
|
|
8199
|
+
return join17(_stateDir, "teams");
|
|
8187
8200
|
}
|
|
8188
8201
|
function getTasksDir() {
|
|
8189
|
-
return
|
|
8202
|
+
return join17(_stateDir, "tasks");
|
|
8190
8203
|
}
|
|
8191
8204
|
function sanitizeName(name) {
|
|
8192
8205
|
return name.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
|
|
8193
8206
|
}
|
|
8194
8207
|
function getTeamDir(teamName) {
|
|
8195
|
-
return
|
|
8208
|
+
return join17(getTeamsDir(), sanitizeName(teamName));
|
|
8196
8209
|
}
|
|
8197
8210
|
function getTeamFilePath(teamName) {
|
|
8198
|
-
return
|
|
8211
|
+
return join17(getTeamDir(teamName), "config.json");
|
|
8199
8212
|
}
|
|
8200
8213
|
function readTeamFile(teamName) {
|
|
8201
8214
|
try {
|
|
8202
|
-
const content =
|
|
8215
|
+
const content = readFileSync11(getTeamFilePath(teamName), "utf-8");
|
|
8203
8216
|
return JSON.parse(content);
|
|
8204
8217
|
} catch (e) {
|
|
8205
8218
|
if (e?.code === "ENOENT") return null;
|
|
@@ -8219,8 +8232,8 @@ async function readTeamFileAsync(teamName) {
|
|
|
8219
8232
|
}
|
|
8220
8233
|
function writeTeamFile(teamName, teamFile) {
|
|
8221
8234
|
const teamDir = getTeamDir(teamName);
|
|
8222
|
-
|
|
8223
|
-
|
|
8235
|
+
mkdirSync8(teamDir, { recursive: true });
|
|
8236
|
+
writeFileSync5(getTeamFilePath(teamName), JSON.stringify(teamFile, null, 2));
|
|
8224
8237
|
}
|
|
8225
8238
|
async function writeTeamFileAsync(teamName, teamFile) {
|
|
8226
8239
|
const teamDir = getTeamDir(teamName);
|
|
@@ -8300,7 +8313,7 @@ async function cleanupTeamDirectories(teamName) {
|
|
|
8300
8313
|
} catch (error) {
|
|
8301
8314
|
console.warn(`[teamHelpers] Failed to clean up team directory ${teamDir}: ${error.message}`);
|
|
8302
8315
|
}
|
|
8303
|
-
const tasksDir =
|
|
8316
|
+
const tasksDir = join17(getTasksDir(), sanitizedName);
|
|
8304
8317
|
try {
|
|
8305
8318
|
await rm(tasksDir, { recursive: true, force: true });
|
|
8306
8319
|
console.log(`[teamHelpers] Cleaned up tasks directory: ${tasksDir}`);
|
|
@@ -8309,8 +8322,8 @@ async function cleanupTeamDirectories(teamName) {
|
|
|
8309
8322
|
}
|
|
8310
8323
|
}
|
|
8311
8324
|
function ensureTasksDir(taskListId) {
|
|
8312
|
-
const dir =
|
|
8313
|
-
|
|
8325
|
+
const dir = join17(getTasksDir(), taskListId);
|
|
8326
|
+
mkdirSync8(dir, { recursive: true });
|
|
8314
8327
|
}
|
|
8315
8328
|
function setLeaderTeamName(name) {
|
|
8316
8329
|
_leaderTeamName = name;
|
|
@@ -8355,9 +8368,9 @@ __export(teammateMailbox_exports, {
|
|
|
8355
8368
|
writeToMailbox: () => writeToMailbox
|
|
8356
8369
|
});
|
|
8357
8370
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
8358
|
-
import { join as
|
|
8371
|
+
import { join as join18 } from "node:path";
|
|
8359
8372
|
function getTeamsDir2() {
|
|
8360
|
-
return
|
|
8373
|
+
return join18(process.env.ENGINE_STATE_DIR || ".", "teams");
|
|
8361
8374
|
}
|
|
8362
8375
|
function sanitizePathComponent(s) {
|
|
8363
8376
|
return s.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
@@ -8366,12 +8379,12 @@ function getInboxPath(agentName, teamName) {
|
|
|
8366
8379
|
const team = teamName || "default";
|
|
8367
8380
|
const safeTeam = sanitizePathComponent(team);
|
|
8368
8381
|
const safeAgentName = sanitizePathComponent(agentName);
|
|
8369
|
-
return
|
|
8382
|
+
return join18(getTeamsDir2(), safeTeam, "inboxes", `${safeAgentName}.json`);
|
|
8370
8383
|
}
|
|
8371
8384
|
async function ensureInboxDir(teamName) {
|
|
8372
8385
|
const team = teamName || "default";
|
|
8373
8386
|
const safeTeam = sanitizePathComponent(team);
|
|
8374
|
-
const inboxDir =
|
|
8387
|
+
const inboxDir = join18(getTeamsDir2(), safeTeam, "inboxes");
|
|
8375
8388
|
await mkdir2(inboxDir, { recursive: true });
|
|
8376
8389
|
}
|
|
8377
8390
|
async function sleep2(ms) {
|
|
@@ -8680,7 +8693,7 @@ var init_inboxPoller = __esm({
|
|
|
8680
8693
|
|
|
8681
8694
|
// src/memory/memdir/memoryScan.ts
|
|
8682
8695
|
import { readdir, stat as stat2, readFile as readFile3 } from "node:fs/promises";
|
|
8683
|
-
import { basename as basename4, join as
|
|
8696
|
+
import { basename as basename4, join as join19, sep as sep3 } from "node:path";
|
|
8684
8697
|
function isArchivedPath(relativePath) {
|
|
8685
8698
|
return relativePath.split(sep3).includes("archive");
|
|
8686
8699
|
}
|
|
@@ -8730,7 +8743,7 @@ async function scanMemoryFiles2(memoryDir, signal, maxFiles) {
|
|
|
8730
8743
|
);
|
|
8731
8744
|
const headerResults = await Promise.allSettled(
|
|
8732
8745
|
mdFiles.map(async (relativePath) => {
|
|
8733
|
-
const filePath =
|
|
8746
|
+
const filePath = join19(memoryDir, relativePath);
|
|
8734
8747
|
const { content, mtimeMs } = await readFileHeader(
|
|
8735
8748
|
filePath,
|
|
8736
8749
|
FRONTMATTER_MAX_LINES,
|
|
@@ -9664,8 +9677,8 @@ var init_filters = __esm({
|
|
|
9664
9677
|
|
|
9665
9678
|
// src/mem7/core/vector-store.ts
|
|
9666
9679
|
import { Schema, Field, Utf8, Float32, Int64, FixedSizeList, TimestampMicrosecond, List } from "apache-arrow";
|
|
9667
|
-
import { mkdirSync as
|
|
9668
|
-
import { join as
|
|
9680
|
+
import { mkdirSync as mkdirSync9 } from "node:fs";
|
|
9681
|
+
import { join as join24 } from "node:path";
|
|
9669
9682
|
function lanceSpecifierFor(platform2, arch) {
|
|
9670
9683
|
return platform2 === "darwin" && arch === "x64" ? "@engine7/lancedb-intel" : "@lancedb/lancedb";
|
|
9671
9684
|
}
|
|
@@ -9761,13 +9774,13 @@ var init_vector_store = __esm({
|
|
|
9761
9774
|
dir;
|
|
9762
9775
|
tables = /* @__PURE__ */ new Map();
|
|
9763
9776
|
constructor(stateDir) {
|
|
9764
|
-
this.dir =
|
|
9777
|
+
this.dir = join24(mem7Root(stateDir), "index", "lancedb");
|
|
9765
9778
|
}
|
|
9766
9779
|
async conn() {
|
|
9767
9780
|
if (!this.db) {
|
|
9768
9781
|
const lance = await loadLance();
|
|
9769
9782
|
if (!lance) throw new Mem7VectorUnavailableError();
|
|
9770
|
-
|
|
9783
|
+
mkdirSync9(this.dir, { recursive: true });
|
|
9771
9784
|
this.db = await lance.connect(this.dir);
|
|
9772
9785
|
}
|
|
9773
9786
|
return this.db;
|
|
@@ -10056,14 +10069,14 @@ Follow these principles when generating episodic memories:
|
|
|
10056
10069
|
|
|
10057
10070
|
// src/mem7/core/store.ts
|
|
10058
10071
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
10059
|
-
import { mkdirSync as
|
|
10060
|
-
import { join as
|
|
10072
|
+
import { mkdirSync as mkdirSync10, readFileSync as readFileSync16, writeFileSync as writeFileSync7, existsSync as existsSync16, readdirSync as readdirSync2 } from "node:fs";
|
|
10073
|
+
import { join as join25 } from "node:path";
|
|
10061
10074
|
import { createHash as createHash2 } from "node:crypto";
|
|
10062
10075
|
function contentHash(text) {
|
|
10063
10076
|
return createHash2("sha256").update(text.replace(/\s+/g, "")).digest("hex").slice(0, 40);
|
|
10064
10077
|
}
|
|
10065
10078
|
function mem7Root(stateDir) {
|
|
10066
|
-
return
|
|
10079
|
+
return join25(stateDir, "mem7");
|
|
10067
10080
|
}
|
|
10068
10081
|
var SCHEMA, Mem7Store;
|
|
10069
10082
|
var init_store2 = __esm({
|
|
@@ -10099,8 +10112,8 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10099
10112
|
constructor(stateDir) {
|
|
10100
10113
|
this.stateDir = stateDir;
|
|
10101
10114
|
this.root = mem7Root(stateDir);
|
|
10102
|
-
|
|
10103
|
-
this.db = new DatabaseSync2(
|
|
10115
|
+
mkdirSync10(join25(this.root, "index"), { recursive: true });
|
|
10116
|
+
this.db = new DatabaseSync2(join25(this.root, "index", "mem7.db"));
|
|
10104
10117
|
this.db.exec("PRAGMA journal_mode=WAL");
|
|
10105
10118
|
this.db.exec(SCHEMA);
|
|
10106
10119
|
}
|
|
@@ -10231,14 +10244,14 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10231
10244
|
/** md 追加通用:frontmatter(存在则更新计数)+ 既有 entry 块全保留 + 追加新块 */
|
|
10232
10245
|
appendMd(ownerId, dirName, filePrefix, type2, dateStr, entries2, render) {
|
|
10233
10246
|
if (entries2.length === 0) return;
|
|
10234
|
-
const dir =
|
|
10235
|
-
|
|
10236
|
-
const file2 =
|
|
10247
|
+
const dir = join25(this.root, "users", ownerId, dirName);
|
|
10248
|
+
mkdirSync10(dir, { recursive: true });
|
|
10249
|
+
const file2 = join25(dir, `${filePrefix}-${dateStr}.md`);
|
|
10237
10250
|
let head;
|
|
10238
10251
|
let existingBlocks = "";
|
|
10239
10252
|
let count;
|
|
10240
|
-
if (
|
|
10241
|
-
const text =
|
|
10253
|
+
if (existsSync16(file2)) {
|
|
10254
|
+
const text = readFileSync16(file2, "utf8");
|
|
10242
10255
|
const fmEnd = text.indexOf("\n---", 3);
|
|
10243
10256
|
const split = fmEnd >= 0 ? fmEnd + 4 : text.length;
|
|
10244
10257
|
head = text.slice(0, split);
|
|
@@ -10269,7 +10282,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10269
10282
|
count++;
|
|
10270
10283
|
}
|
|
10271
10284
|
head = head.replace(/entry_count: \d+/, `entry_count: ${count}`).replace(/last_appended_at: '[^']*'/, `last_appended_at: '${formatMdTimestamp()}'`);
|
|
10272
|
-
|
|
10285
|
+
writeFileSync7(file2, head + "\n\n" + blocks.join("\n\n") + "\n", "utf8");
|
|
10273
10286
|
}
|
|
10274
10287
|
/**
|
|
10275
10288
|
* entry_id:前缀_YYYYMMDD_六位序号。
|
|
@@ -10289,11 +10302,11 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10289
10302
|
af: [".atomic_facts", "atomic-facts"]
|
|
10290
10303
|
};
|
|
10291
10304
|
const [dirName, filePrefix] = dirByPrefix[prefix];
|
|
10292
|
-
const file2 =
|
|
10305
|
+
const file2 = join25(this.root, "users", ownerId, dirName, `${filePrefix}-${dateStr}.md`);
|
|
10293
10306
|
let max = 0;
|
|
10294
|
-
if (
|
|
10307
|
+
if (existsSync16(file2)) {
|
|
10295
10308
|
const re = new RegExp(`${prefix}_${dateStr.replace(/-/g, "")}_(\\d+)`, "g");
|
|
10296
|
-
for (const m of
|
|
10309
|
+
for (const m of readFileSync16(file2, "utf8").matchAll(re)) max = Math.max(max, Number(m[1]));
|
|
10297
10310
|
}
|
|
10298
10311
|
return max;
|
|
10299
10312
|
}
|
|
@@ -10360,17 +10373,17 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10360
10373
|
getOpenPredictions(now, limit = 50) {
|
|
10361
10374
|
const today3 = todayKey(now);
|
|
10362
10375
|
const out = [];
|
|
10363
|
-
const usersDir =
|
|
10364
|
-
if (!
|
|
10376
|
+
const usersDir = join25(this.root, "users");
|
|
10377
|
+
if (!existsSync16(usersDir)) return out;
|
|
10365
10378
|
for (const owner of readdirSync2(usersDir, { withFileTypes: true })) {
|
|
10366
10379
|
if (!owner.isDirectory()) continue;
|
|
10367
|
-
const dir =
|
|
10368
|
-
if (!
|
|
10380
|
+
const dir = join25(usersDir, owner.name, ".foresights");
|
|
10381
|
+
if (!existsSync16(dir)) continue;
|
|
10369
10382
|
for (const f of readdirSync2(dir)) {
|
|
10370
10383
|
if (!/^foresight-\d{4}-\d{2}-\d{2}\.md$/.test(f)) continue;
|
|
10371
10384
|
let content;
|
|
10372
10385
|
try {
|
|
10373
|
-
content =
|
|
10386
|
+
content = readFileSync16(join25(dir, f), "utf8");
|
|
10374
10387
|
} catch {
|
|
10375
10388
|
continue;
|
|
10376
10389
|
}
|
|
@@ -10449,9 +10462,9 @@ var init_ingest2 = __esm({
|
|
|
10449
10462
|
});
|
|
10450
10463
|
|
|
10451
10464
|
// src/mem7/core/ids.ts
|
|
10452
|
-
import { randomBytes as
|
|
10465
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
10453
10466
|
function hex(len) {
|
|
10454
|
-
return
|
|
10467
|
+
return randomBytes4(Math.ceil(len / 2)).toString("hex").slice(0, len);
|
|
10455
10468
|
}
|
|
10456
10469
|
function randomCellId() {
|
|
10457
10470
|
return `mc_${hex(12)}`;
|
|
@@ -10463,9 +10476,9 @@ var init_ids = __esm({
|
|
|
10463
10476
|
});
|
|
10464
10477
|
|
|
10465
10478
|
// src/mem7/core/boundary.ts
|
|
10466
|
-
import { readFileSync as
|
|
10467
|
-
import { join as
|
|
10468
|
-
import { fileURLToPath as
|
|
10479
|
+
import { readFileSync as readFileSync17 } from "node:fs";
|
|
10480
|
+
import { join as join26, dirname as dirname5 } from "node:path";
|
|
10481
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
10469
10482
|
function renderBoundaryInput(messages) {
|
|
10470
10483
|
return messages.map((m, i) => `[${i + 1}] [${new Date(m.tsMs).toISOString()}] ${m.senderName ?? m.senderId}: ${m.text}`).join("\n");
|
|
10471
10484
|
}
|
|
@@ -10558,14 +10571,14 @@ var init_boundary = __esm({
|
|
|
10558
10571
|
HARD_TOKEN_LIMIT = 8192;
|
|
10559
10572
|
HARD_MSG_LIMIT = 50;
|
|
10560
10573
|
RETRIES = 3;
|
|
10561
|
-
PROMPT2 =
|
|
10574
|
+
PROMPT2 = readFileSync17(join26(dirname5(fileURLToPath3(import.meta.url)), "prompts", "boundary.md"), "utf8");
|
|
10562
10575
|
}
|
|
10563
10576
|
});
|
|
10564
10577
|
|
|
10565
10578
|
// src/mem7/core/episode.ts
|
|
10566
|
-
import { readFileSync as
|
|
10567
|
-
import { join as
|
|
10568
|
-
import { fileURLToPath as
|
|
10579
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
10580
|
+
import { join as join27, dirname as dirname6 } from "node:path";
|
|
10581
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
10569
10582
|
function renderConversation(cell) {
|
|
10570
10583
|
return cell.messages.map((m) => `
|
|
10571
10584
|
{
|
|
@@ -10621,14 +10634,14 @@ var init_episode = __esm({
|
|
|
10621
10634
|
"use strict";
|
|
10622
10635
|
init_prompt_render();
|
|
10623
10636
|
RETRIES2 = 2;
|
|
10624
|
-
PROMPT3 =
|
|
10637
|
+
PROMPT3 = readFileSync18(join27(dirname6(fileURLToPath4(import.meta.url)), "prompts", "episode.md"), "utf8");
|
|
10625
10638
|
}
|
|
10626
10639
|
});
|
|
10627
10640
|
|
|
10628
10641
|
// src/mem7/core/atomic-facts.ts
|
|
10629
|
-
import { readFileSync as
|
|
10630
|
-
import { join as
|
|
10631
|
-
import { fileURLToPath as
|
|
10642
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
10643
|
+
import { join as join28, dirname as dirname7 } from "node:path";
|
|
10644
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
10632
10645
|
async function extractAtomicFacts(cell, provider, model) {
|
|
10633
10646
|
const userPrompt = renderPrompt(PROMPT4, {
|
|
10634
10647
|
INPUT_TEXT: renderConversationText(cell.messages),
|
|
@@ -10663,14 +10676,14 @@ var init_atomic_facts = __esm({
|
|
|
10663
10676
|
init_episode();
|
|
10664
10677
|
init_prompt_render();
|
|
10665
10678
|
RETRIES3 = 5;
|
|
10666
|
-
PROMPT4 =
|
|
10679
|
+
PROMPT4 = readFileSync19(join28(dirname7(fileURLToPath5(import.meta.url)), "prompts", "atomic-facts-memcell.md"), "utf8");
|
|
10667
10680
|
}
|
|
10668
10681
|
});
|
|
10669
10682
|
|
|
10670
10683
|
// src/mem7/core/foresight.ts
|
|
10671
|
-
import { readFileSync as
|
|
10672
|
-
import { join as
|
|
10673
|
-
import { fileURLToPath as
|
|
10684
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
10685
|
+
import { join as join29, dirname as dirname8 } from "node:path";
|
|
10686
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
10674
10687
|
function cleanDateString(dateStr) {
|
|
10675
10688
|
if (typeof dateStr !== "string" || !dateStr) return null;
|
|
10676
10689
|
const cleaned = dateStr.replace(/[^\d-]/g, "");
|
|
@@ -10753,7 +10766,7 @@ var init_foresight = __esm({
|
|
|
10753
10766
|
MAX_COUNT = 10;
|
|
10754
10767
|
MIN_COUNT = 4;
|
|
10755
10768
|
TEMPERATURE = 0.3;
|
|
10756
|
-
PROMPT5 =
|
|
10769
|
+
PROMPT5 = readFileSync20(join29(dirname8(fileURLToPath6(import.meta.url)), "prompts", "foresight.md"), "utf8");
|
|
10757
10770
|
}
|
|
10758
10771
|
});
|
|
10759
10772
|
|
|
@@ -10954,7 +10967,7 @@ var init_mem7 = __esm({
|
|
|
10954
10967
|
});
|
|
10955
10968
|
|
|
10956
10969
|
// src/memory/proactive/config.ts
|
|
10957
|
-
import { join as
|
|
10970
|
+
import { join as join30 } from "node:path";
|
|
10958
10971
|
function parseProactiveConfig(raw) {
|
|
10959
10972
|
const obj = raw && typeof raw === "object" ? raw : {};
|
|
10960
10973
|
const modelRef = typeof obj.model === "string" ? obj.model.trim() : "";
|
|
@@ -10981,7 +10994,7 @@ function parseProactiveConfig(raw) {
|
|
|
10981
10994
|
};
|
|
10982
10995
|
}
|
|
10983
10996
|
function proactiveDbPath(workspace) {
|
|
10984
|
-
return
|
|
10997
|
+
return join30(workspace, ".proactive", "proactive.db");
|
|
10985
10998
|
}
|
|
10986
10999
|
var init_config3 = __esm({
|
|
10987
11000
|
"src/memory/proactive/config.ts"() {
|
|
@@ -11325,8 +11338,8 @@ var init_graph_store = __esm({
|
|
|
11325
11338
|
|
|
11326
11339
|
// src/memory/proactive/persistence.ts
|
|
11327
11340
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
11328
|
-
import { mkdirSync as
|
|
11329
|
-
import { dirname as
|
|
11341
|
+
import { mkdirSync as mkdirSync11 } from "node:fs";
|
|
11342
|
+
import { dirname as dirname9 } from "node:path";
|
|
11330
11343
|
function rowToAction(r) {
|
|
11331
11344
|
return {
|
|
11332
11345
|
id: r.id,
|
|
@@ -11427,7 +11440,7 @@ CREATE INDEX IF NOT EXISTS idx_proactive_decisions_created ON proactive_decision
|
|
|
11427
11440
|
Persistence = class {
|
|
11428
11441
|
db;
|
|
11429
11442
|
constructor(dbPath) {
|
|
11430
|
-
|
|
11443
|
+
mkdirSync11(dirname9(dbPath), { recursive: true });
|
|
11431
11444
|
this.db = new DatabaseSync3(dbPath);
|
|
11432
11445
|
this.db.exec("PRAGMA journal_mode=WAL");
|
|
11433
11446
|
this.db.exec(SCHEMA2);
|
|
@@ -12174,8 +12187,8 @@ var init_agent_tools = __esm({
|
|
|
12174
12187
|
});
|
|
12175
12188
|
|
|
12176
12189
|
// src/memory/proactive/prompts.ts
|
|
12177
|
-
import { readFileSync as
|
|
12178
|
-
import { join as
|
|
12190
|
+
import { readFileSync as readFileSync21 } from "node:fs";
|
|
12191
|
+
import { join as join31 } from "node:path";
|
|
12179
12192
|
function buildSectionRegistry(D) {
|
|
12180
12193
|
const SECTION_CORE_ROLE = `You are a cognitive graph update agent for a proactive memory system that maintains a dynamic knowledge graph representing ${D.domain_description}.
|
|
12181
12194
|
|
|
@@ -12787,9 +12800,9 @@ Return your response as JSON.`;
|
|
|
12787
12800
|
}
|
|
12788
12801
|
function loadPersona(workspace) {
|
|
12789
12802
|
if (!workspace) return "";
|
|
12790
|
-
const file2 =
|
|
12803
|
+
const file2 = join31(workspace, "prompts", "proactive-persona.md");
|
|
12791
12804
|
try {
|
|
12792
|
-
const text =
|
|
12805
|
+
const text = readFileSync21(file2, "utf8").trim();
|
|
12793
12806
|
if (text) console.log(`[proactive] persona loaded from ${file2} (${text.length} chars)`);
|
|
12794
12807
|
return text;
|
|
12795
12808
|
} catch {
|
|
@@ -12798,9 +12811,9 @@ function loadPersona(workspace) {
|
|
|
12798
12811
|
}
|
|
12799
12812
|
function loadDomain(workspace) {
|
|
12800
12813
|
if (!workspace) return DEFAULT_DOMAIN;
|
|
12801
|
-
const file2 =
|
|
12814
|
+
const file2 = join31(workspace, "prompts", "proactive-domain.json");
|
|
12802
12815
|
try {
|
|
12803
|
-
const raw = JSON.parse(
|
|
12816
|
+
const raw = JSON.parse(readFileSync21(file2, "utf8"));
|
|
12804
12817
|
if (raw && typeof raw === "object") {
|
|
12805
12818
|
const allowed = new Set(Object.keys(DEFAULT_DOMAIN));
|
|
12806
12819
|
const clean = {};
|
|
@@ -13308,7 +13321,7 @@ var init_helpers = __esm({
|
|
|
13308
13321
|
});
|
|
13309
13322
|
|
|
13310
13323
|
// src/calendar/commands.ts
|
|
13311
|
-
import { existsSync as
|
|
13324
|
+
import { existsSync as existsSync17, statSync as statSync4 } from "node:fs";
|
|
13312
13325
|
import { isAbsolute as isAbsolute4, resolve as resolve6 } from "node:path";
|
|
13313
13326
|
function fmtEnd(start, durationMin) {
|
|
13314
13327
|
const [hh, mm] = start.split(":").map(Number);
|
|
@@ -13477,7 +13490,7 @@ function addTask(db2, args) {
|
|
|
13477
13490
|
}
|
|
13478
13491
|
try {
|
|
13479
13492
|
const absPath = isAbsolute4(docPath) ? docPath : resolve6(process.cwd(), docPath);
|
|
13480
|
-
if (!
|
|
13493
|
+
if (!existsSync17(absPath)) {
|
|
13481
13494
|
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728
|
|
13482
13495
|
\u8DEF\u5F84: ${docPath}
|
|
13483
13496
|
\u89E3\u6790\u540E: ${absPath}
|
|
@@ -13910,8 +13923,8 @@ var init_recall_score = __esm({
|
|
|
13910
13923
|
});
|
|
13911
13924
|
|
|
13912
13925
|
// src/memory/proactive/opportunity.ts
|
|
13913
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
13914
|
-
import { join as
|
|
13926
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync22, existsSync as existsSync18 } from "node:fs";
|
|
13927
|
+
import { join as join32 } from "node:path";
|
|
13915
13928
|
function normalizeOpportunity(raw) {
|
|
13916
13929
|
if (!raw || typeof raw !== "object") return null;
|
|
13917
13930
|
const o = raw;
|
|
@@ -13996,8 +14009,8 @@ function parseForesightEntries(everosRoot, now, userId) {
|
|
|
13996
14009
|
const today3 = todayKey(now);
|
|
13997
14010
|
let files;
|
|
13998
14011
|
if (userId) {
|
|
13999
|
-
const ownDir =
|
|
14000
|
-
files =
|
|
14012
|
+
const ownDir = join32(everosRoot, userId, "default_project", "users", userId, ".foresights");
|
|
14013
|
+
files = existsSync18(ownDir) ? listForesightMds(ownDir) : findForesightFiles(everosRoot);
|
|
14001
14014
|
} else {
|
|
14002
14015
|
files = findForesightFiles(everosRoot);
|
|
14003
14016
|
}
|
|
@@ -14006,7 +14019,7 @@ function parseForesightEntries(everosRoot, now, userId) {
|
|
|
14006
14019
|
for (const file2 of files) {
|
|
14007
14020
|
let content;
|
|
14008
14021
|
try {
|
|
14009
|
-
content =
|
|
14022
|
+
content = readFileSync22(file2, "utf8");
|
|
14010
14023
|
} catch {
|
|
14011
14024
|
continue;
|
|
14012
14025
|
}
|
|
@@ -14046,7 +14059,7 @@ function matchForesightForEvent(entries2, message, maxHits = 2) {
|
|
|
14046
14059
|
}
|
|
14047
14060
|
function listForesightMds(dir) {
|
|
14048
14061
|
try {
|
|
14049
|
-
return readdirSync3(dir).filter((f) => /^foresight-\d{4}-\d{2}-\d{2}\.md$/.test(f)).map((f) =>
|
|
14062
|
+
return readdirSync3(dir).filter((f) => /^foresight-\d{4}-\d{2}-\d{2}\.md$/.test(f)).map((f) => join32(dir, f)).sort();
|
|
14050
14063
|
} catch {
|
|
14051
14064
|
return [];
|
|
14052
14065
|
}
|
|
@@ -14062,7 +14075,7 @@ function findForesightFiles(everosRoot) {
|
|
|
14062
14075
|
return;
|
|
14063
14076
|
}
|
|
14064
14077
|
for (const e of entries2) {
|
|
14065
|
-
const p =
|
|
14078
|
+
const p = join32(dir, e.name);
|
|
14066
14079
|
if (e.isDirectory()) {
|
|
14067
14080
|
if (e.name === ".foresights") {
|
|
14068
14081
|
files.push(...listForesightMds(p));
|
|
@@ -15188,7 +15201,7 @@ var init_intent = __esm({
|
|
|
15188
15201
|
});
|
|
15189
15202
|
|
|
15190
15203
|
// src/memory/proactive/sweep.ts
|
|
15191
|
-
import { readFileSync as
|
|
15204
|
+
import { readFileSync as readFileSync23 } from "node:fs";
|
|
15192
15205
|
function sharesTerm(a, b) {
|
|
15193
15206
|
const x = normalizeTitle(a);
|
|
15194
15207
|
const y = normalizeTitle(b);
|
|
@@ -15408,7 +15421,7 @@ ${JSON.stringify(payload, null, 2)}
|
|
|
15408
15421
|
const file2 = this.deps.promptFile;
|
|
15409
15422
|
if (!file2) return DEFAULT_PROMPT;
|
|
15410
15423
|
try {
|
|
15411
|
-
const text =
|
|
15424
|
+
const text = readFileSync23(file2, "utf8").trim();
|
|
15412
15425
|
return text || DEFAULT_PROMPT;
|
|
15413
15426
|
} catch {
|
|
15414
15427
|
return DEFAULT_PROMPT;
|
|
@@ -15419,14 +15432,14 @@ ${JSON.stringify(payload, null, 2)}
|
|
|
15419
15432
|
});
|
|
15420
15433
|
|
|
15421
15434
|
// src/memory/proactive/proactive-tools.ts
|
|
15422
|
-
import { existsSync as
|
|
15435
|
+
import { existsSync as existsSync19 } from "node:fs";
|
|
15423
15436
|
function setProactiveWorkspace(workspace) {
|
|
15424
15437
|
toolWorkspace = workspace;
|
|
15425
15438
|
}
|
|
15426
15439
|
function withStore(fn) {
|
|
15427
15440
|
if (!toolWorkspace) return null;
|
|
15428
15441
|
const p = proactiveDbPath(toolWorkspace);
|
|
15429
|
-
if (!
|
|
15442
|
+
if (!existsSync19(p)) return null;
|
|
15430
15443
|
const store = new Persistence(p);
|
|
15431
15444
|
try {
|
|
15432
15445
|
return fn(store);
|
|
@@ -15679,8 +15692,8 @@ __export(plugin_exports, {
|
|
|
15679
15692
|
ProactivePlugin: () => ProactivePlugin,
|
|
15680
15693
|
feedMem7Cell: () => feedMem7Cell
|
|
15681
15694
|
});
|
|
15682
|
-
import { join as
|
|
15683
|
-
import { existsSync as
|
|
15695
|
+
import { join as join33 } from "node:path";
|
|
15696
|
+
import { existsSync as existsSync20, readFileSync as readFileSync24, appendFileSync as appendFileSync3 } from "node:fs";
|
|
15684
15697
|
function isFiller(text) {
|
|
15685
15698
|
const t = text.trim();
|
|
15686
15699
|
if (t.length >= 5) return false;
|
|
@@ -15705,7 +15718,7 @@ function buildPlanningContext(calDb, workspace) {
|
|
|
15705
15718
|
}
|
|
15706
15719
|
}
|
|
15707
15720
|
try {
|
|
15708
|
-
const state2 =
|
|
15721
|
+
const state2 = readFileSync24(join33(workspace, "SESSION-STATE.md"), "utf8");
|
|
15709
15722
|
const active = extractActiveState(state2);
|
|
15710
15723
|
if (active) {
|
|
15711
15724
|
lines.push("\n[SESSION-STATE active work]");
|
|
@@ -15902,8 +15915,8 @@ var init_plugin = __esm({
|
|
|
15902
15915
|
});
|
|
15903
15916
|
this.actionAgent = new ActionAgent(this.provider, this.config.modelId, persona);
|
|
15904
15917
|
this.ingestWorkspace = workspace;
|
|
15905
|
-
const calDbPath =
|
|
15906
|
-
this.calDb =
|
|
15918
|
+
const calDbPath = join33(workspace, ".calendar", "calendar.db");
|
|
15919
|
+
this.calDb = existsSync20(calDbPath) ? openDb(workspace) : null;
|
|
15907
15920
|
registerCallbackHook("PostToolUse", {
|
|
15908
15921
|
type: "callback",
|
|
15909
15922
|
id: "proactive-completion-evidence",
|
|
@@ -15942,7 +15955,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
15942
15955
|
const pluginCalDb = this.calDb;
|
|
15943
15956
|
this.sweep = new Sweep({
|
|
15944
15957
|
persist: this.persist,
|
|
15945
|
-
promptFile:
|
|
15958
|
+
promptFile: join33(workspace, "prompts", "proactive.md"),
|
|
15946
15959
|
// 三个都走 getter **每轮现读** —— 热加载规则(config 改了立刻生效)+
|
|
15947
15960
|
// calendar 会变,都不能在 start() 时快照。
|
|
15948
15961
|
get minLeadDays() {
|
|
@@ -15960,7 +15973,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
15960
15973
|
},
|
|
15961
15974
|
// 闸掉的必须留痕:她要能"扫一眼标题,真有冤案我喊"。
|
|
15962
15975
|
onGated: (items) => {
|
|
15963
|
-
const gatedPath =
|
|
15976
|
+
const gatedPath = join33(workspace, ".proactive", "gated.jsonl");
|
|
15964
15977
|
try {
|
|
15965
15978
|
appendFileSync3(
|
|
15966
15979
|
gatedPath,
|
|
@@ -16036,7 +16049,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
16036
16049
|
const nowDate = /* @__PURE__ */ new Date();
|
|
16037
16050
|
const stateDir = String(liveConfig.get("stateDir") ?? "");
|
|
16038
16051
|
if (stateDir) {
|
|
16039
|
-
const all = loadForesightEntries(
|
|
16052
|
+
const all = loadForesightEntries(join33(stateDir, "mem7"), nowDate);
|
|
16040
16053
|
const events = all.filter((e) => e.kind !== "profile");
|
|
16041
16054
|
const mem7Entries = capForesightEntries(events, todayKey(nowDate));
|
|
16042
16055
|
if (all.length > 0) {
|
|
@@ -16178,7 +16191,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
16178
16191
|
if (!stateDir) this.warnOnce("stateDir", "[proactive] stateDir \u4E3A\u7A7A \u2192 mem7 \u53EC\u56DE\u6574\u6BB5\u8DF3\u8FC7\uFF08\u914D\u7F6E/\u521D\u59CB\u5316\u5F02\u5E38\uFF1F\uFF09");
|
|
16179
16192
|
if (senderScoped) console.log(`[proactive] sender-scoped recall owners=[${(scopedOwners ?? []).join(",")}]`);
|
|
16180
16193
|
if (stateDir && scopeReady) {
|
|
16181
|
-
const mem7Entries = loadForesightEntries(
|
|
16194
|
+
const mem7Entries = loadForesightEntries(join33(stateDir, "mem7"), now, void 0, scopedOwners);
|
|
16182
16195
|
const bigram = matchForesightForEvent(mem7Entries, prompt);
|
|
16183
16196
|
for (const h of bigram) hitSet.add(`[mem7] ${h.replace(/^- /, "")}`);
|
|
16184
16197
|
if (bigram.length === 0) {
|
|
@@ -16302,17 +16315,17 @@ ${String(input.tool_output ?? "")}`
|
|
|
16302
16315
|
});
|
|
16303
16316
|
|
|
16304
16317
|
// src/memory/sessionMemory/sessionMemoryUtils.ts
|
|
16305
|
-
import { join as
|
|
16306
|
-
import { mkdirSync as
|
|
16318
|
+
import { join as join34 } from "node:path";
|
|
16319
|
+
import { mkdirSync as mkdirSync12, readFileSync as readFileSync25 } from "node:fs";
|
|
16307
16320
|
function setSessionMemoryStateDir(dir) {
|
|
16308
16321
|
_stateDir2 = dir;
|
|
16309
|
-
|
|
16322
|
+
mkdirSync12(dir, { recursive: true });
|
|
16310
16323
|
}
|
|
16311
16324
|
function getSessionMemoryDir() {
|
|
16312
16325
|
return _stateDir2;
|
|
16313
16326
|
}
|
|
16314
16327
|
function getSessionMemoryPath() {
|
|
16315
|
-
return
|
|
16328
|
+
return join34(_stateDir2, "session-notes.md");
|
|
16316
16329
|
}
|
|
16317
16330
|
function markExtractionStarted() {
|
|
16318
16331
|
extractionStartedAt = Date.now();
|
|
@@ -16360,7 +16373,7 @@ var init_sessionMemoryUtils = __esm({
|
|
|
16360
16373
|
|
|
16361
16374
|
// src/memory/sessionMemory/prompts.ts
|
|
16362
16375
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
16363
|
-
import { join as
|
|
16376
|
+
import { join as join35 } from "node:path";
|
|
16364
16377
|
function roughTokenCountEstimation4(text) {
|
|
16365
16378
|
return Math.ceil(text.length / 4);
|
|
16366
16379
|
}
|
|
@@ -16405,7 +16418,7 @@ REMEMBER: Use the Edit tool in parallel and stop. Do not continue after the edit
|
|
|
16405
16418
|
}
|
|
16406
16419
|
async function loadSessionMemoryTemplate() {
|
|
16407
16420
|
const configHome = process.env.CLAUDE_CONFIG_HOME || process.env.HOME || "";
|
|
16408
|
-
const templatePath =
|
|
16421
|
+
const templatePath = join35(configHome, ".claude", "session-memory", "config", "template.md");
|
|
16409
16422
|
try {
|
|
16410
16423
|
return await readFile4(templatePath, { encoding: "utf-8" });
|
|
16411
16424
|
} catch {
|
|
@@ -16414,7 +16427,7 @@ async function loadSessionMemoryTemplate() {
|
|
|
16414
16427
|
}
|
|
16415
16428
|
async function loadSessionMemoryPrompt() {
|
|
16416
16429
|
const configHome = process.env.CLAUDE_CONFIG_HOME || process.env.HOME || "";
|
|
16417
|
-
const promptPath =
|
|
16430
|
+
const promptPath = join35(configHome, ".claude", "session-memory", "config", "prompt.md");
|
|
16418
16431
|
try {
|
|
16419
16432
|
return await readFile4(promptPath, { encoding: "utf-8" });
|
|
16420
16433
|
} catch {
|
|
@@ -16578,7 +16591,7 @@ __export(sessionMemory_exports, {
|
|
|
16578
16591
|
resetLastMemoryMessageUuid: () => resetLastMemoryMessageUuid,
|
|
16579
16592
|
shouldExtractMemory: () => shouldExtractMemory
|
|
16580
16593
|
});
|
|
16581
|
-
import { readFileSync as
|
|
16594
|
+
import { readFileSync as readFileSync26, mkdirSync as mkdirSync13 } from "node:fs";
|
|
16582
16595
|
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
16583
16596
|
function initSessionMemory(deps) {
|
|
16584
16597
|
_deps = deps;
|
|
@@ -16637,11 +16650,11 @@ function shouldExtractMemory(estimatedTokens, messages) {
|
|
|
16637
16650
|
}
|
|
16638
16651
|
async function setupSessionMemoryFile() {
|
|
16639
16652
|
const memoryDir = getSessionMemoryDir();
|
|
16640
|
-
|
|
16653
|
+
mkdirSync13(memoryDir, { recursive: true });
|
|
16641
16654
|
const memoryPath = getSessionMemoryPath();
|
|
16642
16655
|
let currentMemory;
|
|
16643
16656
|
try {
|
|
16644
|
-
currentMemory =
|
|
16657
|
+
currentMemory = readFileSync26(memoryPath, { encoding: "utf-8" });
|
|
16645
16658
|
} catch {
|
|
16646
16659
|
const template = await loadSessionMemoryTemplate();
|
|
16647
16660
|
await writeFile3(memoryPath, template, { encoding: "utf-8" });
|
|
@@ -16718,7 +16731,7 @@ ${messages.filter((m) => m.role === "user" || m.role === "assistant").slice(-20)
|
|
|
16718
16731
|
}
|
|
16719
16732
|
function getSessionMemoryForCompaction() {
|
|
16720
16733
|
try {
|
|
16721
|
-
const content =
|
|
16734
|
+
const content = readFileSync26(getSessionMemoryPath(), { encoding: "utf-8" }).trim();
|
|
16722
16735
|
if (!content) return null;
|
|
16723
16736
|
const { truncatedContent, wasTruncated } = truncateSessionMemoryForCompact(content);
|
|
16724
16737
|
if (wasTruncated) {
|
|
@@ -16751,9 +16764,9 @@ var init_sessionMemory = __esm({
|
|
|
16751
16764
|
|
|
16752
16765
|
// src/memory/autoDream/consolidationLock.ts
|
|
16753
16766
|
import { mkdir as mkdir3, readFile as readFile5, stat as stat3, unlink, utimes, writeFile as writeFile4 } from "node:fs/promises";
|
|
16754
|
-
import { join as
|
|
16767
|
+
import { join as join36 } from "node:path";
|
|
16755
16768
|
function lockPath(memoryDir) {
|
|
16756
|
-
return
|
|
16769
|
+
return join36(memoryDir, LOCK_FILE);
|
|
16757
16770
|
}
|
|
16758
16771
|
async function readLastConsolidatedAt(memoryDir) {
|
|
16759
16772
|
try {
|
|
@@ -16821,7 +16834,7 @@ async function listSessionsTouchedSince(sessionsDir, sinceMs) {
|
|
|
16821
16834
|
const results = [];
|
|
16822
16835
|
for (const f of jsonlFiles) {
|
|
16823
16836
|
try {
|
|
16824
|
-
const s = await stat3(
|
|
16837
|
+
const s = await stat3(join36(sessionsDir, f));
|
|
16825
16838
|
if (s.mtimeMs > sinceMs) {
|
|
16826
16839
|
results.push(f.replace(/\.jsonl$/, ""));
|
|
16827
16840
|
}
|
|
@@ -18357,18 +18370,18 @@ var init_tasks2 = __esm({
|
|
|
18357
18370
|
});
|
|
18358
18371
|
|
|
18359
18372
|
// src/version.ts
|
|
18360
|
-
import { readFileSync as
|
|
18361
|
-
import { dirname as
|
|
18362
|
-
import { fileURLToPath as
|
|
18373
|
+
import { readFileSync as readFileSync32 } from "node:fs";
|
|
18374
|
+
import { dirname as dirname11, join as join44 } from "node:path";
|
|
18375
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
18363
18376
|
function candidates() {
|
|
18364
|
-
if (_pkgDirOverride !== null) return [
|
|
18365
|
-
const here =
|
|
18366
|
-
return [
|
|
18377
|
+
if (_pkgDirOverride !== null) return [join44(_pkgDirOverride, "package.json")];
|
|
18378
|
+
const here = dirname11(fileURLToPath7(import.meta.url));
|
|
18379
|
+
return [join44(here, "..", "package.json"), join44(here, "..", "..", "package.json")];
|
|
18367
18380
|
}
|
|
18368
18381
|
function readFromDisk() {
|
|
18369
18382
|
for (const p of candidates()) {
|
|
18370
18383
|
try {
|
|
18371
|
-
return JSON.parse(
|
|
18384
|
+
return JSON.parse(readFileSync32(p, "utf-8")).version || "unknown";
|
|
18372
18385
|
} catch {
|
|
18373
18386
|
}
|
|
18374
18387
|
}
|
|
@@ -18517,8 +18530,8 @@ var reply_blocklist_exports = {};
|
|
|
18517
18530
|
__export(reply_blocklist_exports, {
|
|
18518
18531
|
isUserBlocked: () => isUserBlocked
|
|
18519
18532
|
});
|
|
18520
|
-
import { readFileSync as
|
|
18521
|
-
import { join as
|
|
18533
|
+
import { readFileSync as readFileSync33, writeFileSync as writeFileSync11, existsSync as existsSync24 } from "node:fs";
|
|
18534
|
+
import { join as join45 } from "node:path";
|
|
18522
18535
|
function ensureLoaded(workspace, configIds) {
|
|
18523
18536
|
if (loaded) return;
|
|
18524
18537
|
if (configIds?.length) {
|
|
@@ -18526,10 +18539,10 @@ function ensureLoaded(workspace, configIds) {
|
|
|
18526
18539
|
if (!state.blockedUserIds.includes(id)) state.blockedUserIds.push(id);
|
|
18527
18540
|
}
|
|
18528
18541
|
}
|
|
18529
|
-
const path61 =
|
|
18542
|
+
const path61 = join45(workspace, ".reply-blocklist.json");
|
|
18530
18543
|
try {
|
|
18531
|
-
if (
|
|
18532
|
-
const raw =
|
|
18544
|
+
if (existsSync24(path61)) {
|
|
18545
|
+
const raw = readFileSync33(path61, "utf-8");
|
|
18533
18546
|
const parsed = JSON.parse(raw);
|
|
18534
18547
|
if (parsed.blockedUserIds) {
|
|
18535
18548
|
for (const id of parsed.blockedUserIds) {
|
|
@@ -18545,9 +18558,9 @@ function ensureLoaded(workspace, configIds) {
|
|
|
18545
18558
|
loaded = true;
|
|
18546
18559
|
}
|
|
18547
18560
|
function save(workspace) {
|
|
18548
|
-
const path61 =
|
|
18561
|
+
const path61 = join45(workspace, ".reply-blocklist.json");
|
|
18549
18562
|
try {
|
|
18550
|
-
|
|
18563
|
+
writeFileSync11(path61, JSON.stringify(state, null, 2), "utf-8");
|
|
18551
18564
|
} catch (err) {
|
|
18552
18565
|
console.warn(`[reply-blocklist] Failed to save: ${err.message}`);
|
|
18553
18566
|
}
|
|
@@ -23662,6 +23675,7 @@ function startConfigWatcher(config, deps, provider) {
|
|
|
23662
23675
|
}
|
|
23663
23676
|
});
|
|
23664
23677
|
};
|
|
23678
|
+
consumeSelfWrite();
|
|
23665
23679
|
startWatch();
|
|
23666
23680
|
console.log(`[config-watch] watching ${configPath}`);
|
|
23667
23681
|
try {
|
|
@@ -23776,17 +23790,81 @@ import * as path16 from "node:path";
|
|
|
23776
23790
|
import fs11 from "node:fs";
|
|
23777
23791
|
import path11 from "node:path";
|
|
23778
23792
|
import { execSync as execSync2 } from "node:child_process";
|
|
23779
|
-
function
|
|
23780
|
-
|
|
23781
|
-
|
|
23793
|
+
function enginePidFile(stateDir) {
|
|
23794
|
+
return path11.join(stateDir, ".engine.pid");
|
|
23795
|
+
}
|
|
23796
|
+
function isEngineImage(text) {
|
|
23797
|
+
return /node|engine7|electron/i.test(text);
|
|
23798
|
+
}
|
|
23799
|
+
function isPidAlive(pid) {
|
|
23800
|
+
try {
|
|
23801
|
+
process.kill(pid, 0);
|
|
23802
|
+
return true;
|
|
23803
|
+
} catch {
|
|
23804
|
+
return false;
|
|
23805
|
+
}
|
|
23806
|
+
}
|
|
23807
|
+
function probeImage(pid) {
|
|
23782
23808
|
try {
|
|
23783
|
-
|
|
23784
|
-
|
|
23785
|
-
|
|
23786
|
-
|
|
23809
|
+
if (process.platform === "win32") {
|
|
23810
|
+
return execSync2(`tasklist /FI "PID eq ${pid}" /NH /FO CSV`, {
|
|
23811
|
+
encoding: "utf-8",
|
|
23812
|
+
timeout: 3e3,
|
|
23813
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
23814
|
+
});
|
|
23815
|
+
}
|
|
23816
|
+
if (process.platform === "darwin") {
|
|
23817
|
+
return execSync2(`ps -p ${pid} -o comm=`, {
|
|
23818
|
+
encoding: "utf-8",
|
|
23819
|
+
timeout: 3e3,
|
|
23820
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
23821
|
+
});
|
|
23787
23822
|
}
|
|
23823
|
+
return fs11.readFileSync(`/proc/${pid}/comm`, "utf-8");
|
|
23824
|
+
} catch {
|
|
23825
|
+
return null;
|
|
23826
|
+
}
|
|
23827
|
+
}
|
|
23828
|
+
function probeEngineImage(pid) {
|
|
23829
|
+
return isEngineImage(probeImage(pid) ?? "");
|
|
23830
|
+
}
|
|
23831
|
+
function isCliWrapperImage(text) {
|
|
23832
|
+
return /node/i.test(text);
|
|
23833
|
+
}
|
|
23834
|
+
function probeIsCliWrapper(pid) {
|
|
23835
|
+
return isCliWrapperImage(probeImage(pid) ?? "");
|
|
23836
|
+
}
|
|
23837
|
+
function readOwnEnginePidText(stateDir) {
|
|
23838
|
+
try {
|
|
23839
|
+
return fs11.readFileSync(enginePidFile(stateDir), "utf-8");
|
|
23788
23840
|
} catch (err) {
|
|
23789
23841
|
if (err?.code !== "ENOENT") console.warn(`[pid-lock] read lock failed: ${err.message}`);
|
|
23842
|
+
return null;
|
|
23843
|
+
}
|
|
23844
|
+
}
|
|
23845
|
+
function pickOwnEnginePid(probe) {
|
|
23846
|
+
const pid = parseInt((probe.pidFileContent ?? "").trim(), 10);
|
|
23847
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
23848
|
+
if (pid === probe.myPid) return null;
|
|
23849
|
+
if (!probe.isAlive(pid)) return null;
|
|
23850
|
+
if (!probe.isEngineImage(pid)) return null;
|
|
23851
|
+
return pid;
|
|
23852
|
+
}
|
|
23853
|
+
function ownEnginePid(stateDir, myPid = process.pid) {
|
|
23854
|
+
return pickOwnEnginePid({
|
|
23855
|
+
pidFileContent: readOwnEnginePidText(stateDir),
|
|
23856
|
+
myPid,
|
|
23857
|
+
isAlive: isPidAlive,
|
|
23858
|
+
isEngineImage: probeEngineImage
|
|
23859
|
+
});
|
|
23860
|
+
}
|
|
23861
|
+
function acquireEngineLock(stateDir) {
|
|
23862
|
+
const lockFile = enginePidFile(stateDir);
|
|
23863
|
+
const myPid = process.pid;
|
|
23864
|
+
const stale = ownEnginePid(stateDir, myPid);
|
|
23865
|
+
if (stale !== null) {
|
|
23866
|
+
console.log(`[pid-lock] Stale engine PID ${stale} still alive (engine), killing tree...`);
|
|
23867
|
+
killTree(stale);
|
|
23790
23868
|
}
|
|
23791
23869
|
try {
|
|
23792
23870
|
fs11.mkdirSync(stateDir, { recursive: true });
|
|
@@ -23812,54 +23890,42 @@ function acquireEngineLock(stateDir) {
|
|
|
23812
23890
|
process.exit(0);
|
|
23813
23891
|
});
|
|
23814
23892
|
}
|
|
23815
|
-
function
|
|
23816
|
-
|
|
23817
|
-
|
|
23818
|
-
|
|
23819
|
-
|
|
23820
|
-
}
|
|
23821
|
-
try {
|
|
23822
|
-
if (process.platform === "win32") {
|
|
23823
|
-
const out = execSync2(`tasklist /FI "PID eq ${pid}" /NH /FO CSV`, {
|
|
23824
|
-
encoding: "utf-8",
|
|
23825
|
-
timeout: 3e3,
|
|
23826
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
23827
|
-
});
|
|
23828
|
-
return /node\.exe/i.test(out);
|
|
23829
|
-
} else if (process.platform === "darwin") {
|
|
23830
|
-
const out = execSync2(`ps -p ${pid} -o comm=`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] });
|
|
23831
|
-
return /node/.test(out);
|
|
23832
|
-
}
|
|
23833
|
-
return /node/.test(fs11.readFileSync(`/proc/${pid}/cmdline`, "utf-8"));
|
|
23834
|
-
} catch {
|
|
23835
|
-
return false;
|
|
23836
|
-
}
|
|
23893
|
+
function pickParentPid(procStatus, psOutput) {
|
|
23894
|
+
const fromProc = Number(/PPid:\s*(\d+)/.exec(procStatus ?? "")?.[1] ?? NaN);
|
|
23895
|
+
if (Number.isInteger(fromProc) && fromProc > 0) return fromProc;
|
|
23896
|
+
const fromPs = Number((psOutput ?? "").trim());
|
|
23897
|
+
return Number.isInteger(fromPs) && fromPs > 0 ? fromPs : 0;
|
|
23837
23898
|
}
|
|
23838
23899
|
function killTree(pid) {
|
|
23839
23900
|
try {
|
|
23840
23901
|
if (process.platform === "win32") {
|
|
23841
23902
|
execSync2(`taskkill /PID ${pid} /T /F`, { stdio: "ignore", timeout: 8e3 });
|
|
23842
23903
|
try {
|
|
23843
|
-
const parentPid = execSync2(`wmic process where ProcessId=${pid} get ParentProcessId /value`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).match(/ParentProcessId=(\d+)/)?.[1];
|
|
23844
|
-
if (parentPid &&
|
|
23904
|
+
const parentPid = parseInt(execSync2(`wmic process where ProcessId=${pid} get ParentProcessId /value`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).match(/ParentProcessId=(\d+)/)?.[1] ?? "0", 10);
|
|
23905
|
+
if (parentPid && parentPid !== process.ppid && probeIsCliWrapper(parentPid)) {
|
|
23845
23906
|
execSync2(`taskkill /PID ${parentPid} /F`, { stdio: "ignore", timeout: 3e3 });
|
|
23846
23907
|
}
|
|
23847
23908
|
} catch {
|
|
23848
23909
|
}
|
|
23849
23910
|
} else {
|
|
23850
23911
|
process.kill(pid, "SIGKILL");
|
|
23912
|
+
let parentPid = 0;
|
|
23851
23913
|
try {
|
|
23852
|
-
|
|
23853
|
-
const macPpid = parseInt(execSync2(`ps -p ${pid} -o ppid=`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim(), 10);
|
|
23854
|
-
const parentPid = ppid || macPpid;
|
|
23855
|
-
if (parentPid && parentPid > 1) {
|
|
23856
|
-
try {
|
|
23857
|
-
process.kill(parentPid, "SIGKILL");
|
|
23858
|
-
} catch {
|
|
23859
|
-
}
|
|
23860
|
-
}
|
|
23914
|
+
parentPid = pickParentPid(fs11.readFileSync(`/proc/${pid}/status`, "utf-8"), null);
|
|
23861
23915
|
} catch {
|
|
23862
23916
|
}
|
|
23917
|
+
if (!parentPid) {
|
|
23918
|
+
try {
|
|
23919
|
+
parentPid = pickParentPid(null, execSync2(`ps -p ${pid} -o ppid=`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }));
|
|
23920
|
+
} catch {
|
|
23921
|
+
}
|
|
23922
|
+
}
|
|
23923
|
+
if (parentPid > 1 && parentPid !== process.ppid && probeIsCliWrapper(parentPid)) {
|
|
23924
|
+
try {
|
|
23925
|
+
process.kill(parentPid, "SIGKILL");
|
|
23926
|
+
} catch {
|
|
23927
|
+
}
|
|
23928
|
+
}
|
|
23863
23929
|
}
|
|
23864
23930
|
} catch (err) {
|
|
23865
23931
|
console.warn(`[pid-lock] kill ${pid} failed: ${err.message}`);
|
|
@@ -25472,6 +25538,18 @@ var FIELDS = [
|
|
|
25472
25538
|
|
|
25473
25539
|
// src/cli-init-config.ts
|
|
25474
25540
|
var FREE_TIER_RELAY_URL = "https://www.twinsun.top:8866";
|
|
25541
|
+
var FREE_TIER_PROVIDER_ID = "7yi";
|
|
25542
|
+
var DEFAULT_FREE_VOICE = "Chinese (Mandarin)_Warm_Girl";
|
|
25543
|
+
function freeTierVoiceConfig(existing) {
|
|
25544
|
+
const mv = existing && typeof existing === "object" ? existing : {};
|
|
25545
|
+
return {
|
|
25546
|
+
...mv,
|
|
25547
|
+
provider: "relay",
|
|
25548
|
+
relayProviderId: FREE_TIER_PROVIDER_ID,
|
|
25549
|
+
relayModel: "engine7-tts",
|
|
25550
|
+
voice: mv.voice || DEFAULT_FREE_VOICE
|
|
25551
|
+
};
|
|
25552
|
+
}
|
|
25475
25553
|
var VISION_CAPABLE = {
|
|
25476
25554
|
// 0917:原先标 true,但同一个文件里 qwen3.8-max 的 input 是 ['text'],安装器目录
|
|
25477
25555
|
// 也明确标 vision=false(只有 Flash 叫"多模态")。矛盾直接导致**默认 CLI 装机路径**
|
|
@@ -25706,6 +25784,104 @@ function applyFreeTierVideoFixup(io) {
|
|
|
25706
25784
|
return changed;
|
|
25707
25785
|
}
|
|
25708
25786
|
|
|
25787
|
+
// src/provision-free.ts
|
|
25788
|
+
import { randomBytes as randomBytes2, randomUUID as randomUUID5 } from "node:crypto";
|
|
25789
|
+
import { chmodSync, existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync3 } from "node:fs";
|
|
25790
|
+
import { dirname as dirname3, join as join14 } from "node:path";
|
|
25791
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
25792
|
+
var __filename = fileURLToPath2(import.meta.url);
|
|
25793
|
+
var IDENTITY_FILE = "install-identity.json";
|
|
25794
|
+
function readContactEmailOf(parsed) {
|
|
25795
|
+
return typeof parsed?.contactEmail === "string" ? parsed.contactEmail.trim() : "";
|
|
25796
|
+
}
|
|
25797
|
+
function loadOrCreateInstallIdentity(stateDir) {
|
|
25798
|
+
const file2 = join14(stateDir, IDENTITY_FILE);
|
|
25799
|
+
if (existsSync9(file2)) {
|
|
25800
|
+
let parsed;
|
|
25801
|
+
try {
|
|
25802
|
+
parsed = JSON.parse(readFileSync8(file2, "utf8"));
|
|
25803
|
+
} catch (e) {
|
|
25804
|
+
throw new Error(
|
|
25805
|
+
`${IDENTITY_FILE} \u5B58\u5728\u4F46\u4E0D\u662F\u5408\u6CD5 JSON\uFF08${e.message}\uFF09\u2014\u2014\u5220\u6389\u5B83\u91CD\u8DD1\u4F1A\u9886\u4E00\u628A\u65B0\u4EE4\u724C\uFF0C\u65E7\u7684\u90A3\u628A\u53D6\u4E0D\u56DE\u6765`
|
|
25806
|
+
);
|
|
25807
|
+
}
|
|
25808
|
+
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
25809
|
+
throw new Error(`${IDENTITY_FILE} \u7F3A installId / installSecret \u5B57\u6BB5`);
|
|
25810
|
+
}
|
|
25811
|
+
const email = readContactEmailOf(parsed);
|
|
25812
|
+
return {
|
|
25813
|
+
installId: parsed.installId,
|
|
25814
|
+
installSecret: parsed.installSecret,
|
|
25815
|
+
...email ? { contactEmail: email } : {}
|
|
25816
|
+
};
|
|
25817
|
+
}
|
|
25818
|
+
const identity = {
|
|
25819
|
+
// 服务端校验 installId 长度为 8..36、只允许字母数字和连字符;uuid 正好符合
|
|
25820
|
+
installId: randomUUID5(),
|
|
25821
|
+
// 服务端校验 installSecret 为 32..64 位十六进制
|
|
25822
|
+
installSecret: randomBytes2(32).toString("hex")
|
|
25823
|
+
};
|
|
25824
|
+
mkdirSync6(stateDir, { recursive: true });
|
|
25825
|
+
writeFileSync3(file2, JSON.stringify(identity, null, 2) + "\n", { mode: 384 });
|
|
25826
|
+
try {
|
|
25827
|
+
chmodSync(file2, 384);
|
|
25828
|
+
} catch {
|
|
25829
|
+
}
|
|
25830
|
+
return identity;
|
|
25831
|
+
}
|
|
25832
|
+
function readInstallIdentityDetailed(stateDir) {
|
|
25833
|
+
const file2 = join14(stateDir, IDENTITY_FILE);
|
|
25834
|
+
if (!existsSync9(file2)) return { ok: false, reason: "missing" };
|
|
25835
|
+
let text;
|
|
25836
|
+
try {
|
|
25837
|
+
text = readFileSync8(file2, "utf8");
|
|
25838
|
+
} catch (e) {
|
|
25839
|
+
return { ok: false, reason: "corrupt", detail: `\u5B58\u5728\u4F46\u8BFB\u4E0D\u4E86\uFF08${e?.message ?? e}\uFF09` };
|
|
25840
|
+
}
|
|
25841
|
+
let parsed;
|
|
25842
|
+
try {
|
|
25843
|
+
parsed = JSON.parse(text);
|
|
25844
|
+
} catch (e) {
|
|
25845
|
+
return { ok: false, reason: "corrupt", detail: `\u4E0D\u662F\u5408\u6CD5 JSON\uFF08${e?.message ?? e}\uFF09` };
|
|
25846
|
+
}
|
|
25847
|
+
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
25848
|
+
return { ok: false, reason: "corrupt", detail: "\u7F3A installId / installSecret \u5B57\u6BB5" };
|
|
25849
|
+
}
|
|
25850
|
+
const email = readContactEmailOf(parsed);
|
|
25851
|
+
return {
|
|
25852
|
+
ok: true,
|
|
25853
|
+
identity: {
|
|
25854
|
+
installId: parsed.installId,
|
|
25855
|
+
installSecret: parsed.installSecret,
|
|
25856
|
+
...email ? { contactEmail: email } : {}
|
|
25857
|
+
}
|
|
25858
|
+
};
|
|
25859
|
+
}
|
|
25860
|
+
|
|
25861
|
+
// src/free-tier-apply.ts
|
|
25862
|
+
function isFreeTierConfig(cfg) {
|
|
25863
|
+
const hasProvider = !!cfg?.models?.providers?.[FREE_TIER_PROVIDER_ID];
|
|
25864
|
+
const primary = String(cfg?.agents?.defaults?.model?.primary || "");
|
|
25865
|
+
return hasProvider && primary.startsWith(`${FREE_TIER_PROVIDER_ID}/`);
|
|
25866
|
+
}
|
|
25867
|
+
|
|
25868
|
+
// src/startup/free-tier-voice-fixup.ts
|
|
25869
|
+
function needsFreeTierVoiceFixup(cfg) {
|
|
25870
|
+
if (!isFreeTierConfig(cfg)) return false;
|
|
25871
|
+
return cfg?.tools?.my_voice === void 0;
|
|
25872
|
+
}
|
|
25873
|
+
async function applyFreeTierVoiceFixup(io) {
|
|
25874
|
+
const cfg = io.all();
|
|
25875
|
+
if (!needsFreeTierVoiceFixup(cfg)) return false;
|
|
25876
|
+
const persisted = await io.set("tools.my_voice", freeTierVoiceConfig());
|
|
25877
|
+
if (persisted === false) {
|
|
25878
|
+
console.error("[startup] \u514D\u8D39\u6863\u8865\u9F50 tools.my_voice **\u672A\u843D\u76D8**\uFF08\u672C\u6B21\u8FD0\u884C\u5185\u5B58\u91CC\u5DF2\u751F\u6548\uFF0C\u914D\u7F6E\u6587\u4EF6\u4ECD\u662F\u65E7\u7684\u2014\u2014\u6258\u76D8/\u4E0B\u6B21\u542F\u52A8\u770B\u5230\u7684\u8FD8\u662F edge-tts\uFF09\u3002\u4E0A\u9762 [liveConfig] \u90A3\u884C\u662F\u539F\u56E0\u3002");
|
|
25879
|
+
return true;
|
|
25880
|
+
}
|
|
25881
|
+
console.log("[startup] \u514D\u8D39\u6863\u8865\u9F50 tools.my_voice \u2192 7yi\uFF08\u5347\u7EA7\u524D\u88C5\u7684\u673A\u5668\u8FD9\u5757\u4ECE\u672A\u88AB\u5199\u8FC7\uFF0C\u8BED\u97F3\u6761\u6B64\u524D\u843D\u5230 edge-tts\uFF1B\u7528\u6237\u81EA\u5DF1\u914D\u8FC7\u7684\u4E0D\u52A8\uFF09");
|
|
25882
|
+
return true;
|
|
25883
|
+
}
|
|
25884
|
+
|
|
25709
25885
|
// src/startup/hooks-boot.ts
|
|
25710
25886
|
init_live();
|
|
25711
25887
|
import * as fs23 from "node:fs";
|
|
@@ -26759,7 +26935,7 @@ ${manifest}`
|
|
|
26759
26935
|
// src/memory/memdir/findRelevantMemoriesVector.ts
|
|
26760
26936
|
init_well_formed();
|
|
26761
26937
|
import { statSync as statSync3 } from "node:fs";
|
|
26762
|
-
import { join as
|
|
26938
|
+
import { join as join20, resolve as resolve5, sep as sep4 } from "node:path";
|
|
26763
26939
|
import { createRequire as createRequire2 } from "node:module";
|
|
26764
26940
|
var require2 = createRequire2(import.meta.url);
|
|
26765
26941
|
var DEFAULT_TOP_K = 3;
|
|
@@ -26912,7 +27088,7 @@ async function findRelevantMemoriesVector(query, memoryDir, alreadySurfaced = /*
|
|
|
26912
27088
|
}
|
|
26913
27089
|
const scored = [];
|
|
26914
27090
|
for (const row of rows) {
|
|
26915
|
-
const absPath =
|
|
27091
|
+
const absPath = join20(memoryDir, row.file_path.replace(/\//g, sep4));
|
|
26916
27092
|
if (alreadySurfaced.has(absPath) || alreadySurfaced.has(row.file_path)) continue;
|
|
26917
27093
|
const emb = new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4);
|
|
26918
27094
|
const score = cosineSim(qVec, emb);
|
|
@@ -27125,27 +27301,27 @@ ${ep.episode || ep.summary}`,
|
|
|
27125
27301
|
|
|
27126
27302
|
// src/handle-query.ts
|
|
27127
27303
|
init_paths();
|
|
27128
|
-
import { readFileSync as
|
|
27129
|
-
import { join as
|
|
27304
|
+
import { readFileSync as readFileSync27, existsSync as existsSync21, statSync as statSync5 } from "node:fs";
|
|
27305
|
+
import { join as join37, resolve as resolve7 } from "node:path";
|
|
27130
27306
|
import * as path21 from "node:path";
|
|
27131
27307
|
|
|
27132
27308
|
// src/light-mode.ts
|
|
27133
27309
|
init_live();
|
|
27134
|
-
import { readFileSync as
|
|
27310
|
+
import { readFileSync as readFileSync13 } from "node:fs";
|
|
27135
27311
|
|
|
27136
27312
|
// src/config/persona-files.ts
|
|
27137
|
-
import { existsSync as
|
|
27138
|
-
import { join as
|
|
27313
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
27314
|
+
import { join as join21 } from "node:path";
|
|
27139
27315
|
var LEGACY_RELATIVE = {
|
|
27140
27316
|
"my-inner-voice.md": "prompts/my-inner-voice.md"
|
|
27141
27317
|
};
|
|
27142
27318
|
function resolvePersonaFile(workspace, persona, name) {
|
|
27143
27319
|
if (persona) {
|
|
27144
|
-
const scoped =
|
|
27145
|
-
if (
|
|
27320
|
+
const scoped = join21(workspace, "personas", persona, name);
|
|
27321
|
+
if (existsSync12(scoped)) return scoped;
|
|
27146
27322
|
}
|
|
27147
|
-
const legacy =
|
|
27148
|
-
return
|
|
27323
|
+
const legacy = join21(workspace, LEGACY_RELATIVE[name] ?? name);
|
|
27324
|
+
return existsSync12(legacy) ? legacy : null;
|
|
27149
27325
|
}
|
|
27150
27326
|
|
|
27151
27327
|
// src/light-mode.ts
|
|
@@ -27186,7 +27362,7 @@ function buildLightStablePrompt(workspace, mode, opts) {
|
|
|
27186
27362
|
const filePath = resolvePersonaFile(workspace, persona, f);
|
|
27187
27363
|
if (!filePath) continue;
|
|
27188
27364
|
try {
|
|
27189
|
-
parts.push(
|
|
27365
|
+
parts.push(readFileSync13(filePath, "utf-8").trim());
|
|
27190
27366
|
} catch {
|
|
27191
27367
|
}
|
|
27192
27368
|
}
|
|
@@ -27270,8 +27446,8 @@ function voiceFastView(history, opts = VOICE_FAST_DEFAULTS) {
|
|
|
27270
27446
|
|
|
27271
27447
|
// src/sender-context.ts
|
|
27272
27448
|
init_clock();
|
|
27273
|
-
import { readFileSync as
|
|
27274
|
-
import { join as
|
|
27449
|
+
import { readFileSync as readFileSync14, existsSync as existsSync14 } from "node:fs";
|
|
27450
|
+
import { join as join22 } from "node:path";
|
|
27275
27451
|
var contactMap = null;
|
|
27276
27452
|
var externalChanWhitelist = null;
|
|
27277
27453
|
function loadContactMap(workspace) {
|
|
@@ -27279,10 +27455,10 @@ function loadContactMap(workspace) {
|
|
|
27279
27455
|
contactMap = /* @__PURE__ */ new Map();
|
|
27280
27456
|
externalChanWhitelist = /* @__PURE__ */ new Set();
|
|
27281
27457
|
try {
|
|
27282
|
-
const contactsPath =
|
|
27283
|
-
console.log(`[meta] Loading contacts from ${contactsPath}, exists=${
|
|
27284
|
-
if (
|
|
27285
|
-
const text =
|
|
27458
|
+
const contactsPath = join22(workspace, "prompts", "contacts.md");
|
|
27459
|
+
console.log(`[meta] Loading contacts from ${contactsPath}, exists=${existsSync14(contactsPath)}`);
|
|
27460
|
+
if (existsSync14(contactsPath)) {
|
|
27461
|
+
const text = readFileSync14(contactsPath, "utf-8");
|
|
27286
27462
|
const lines = text.split("\n");
|
|
27287
27463
|
for (const line of lines) {
|
|
27288
27464
|
const m = line.match(/^\|\s*(.+?)\s*\|\s*([a-zA-Z0-9_@.]+)\s*\|/);
|
|
@@ -27371,12 +27547,12 @@ function resetSessionStartInjection(sessionId) {
|
|
|
27371
27547
|
}
|
|
27372
27548
|
var externalChanRulesCache = null;
|
|
27373
27549
|
function loadExternalChanRules(workspace) {
|
|
27374
|
-
const path61 =
|
|
27550
|
+
const path61 = join37(workspace, "prompts", "external-chan-rules.md");
|
|
27375
27551
|
if (externalChanRulesCache && externalChanRulesCache.path === path61) return externalChanRulesCache;
|
|
27376
27552
|
let content = "";
|
|
27377
|
-
if (
|
|
27553
|
+
if (existsSync21(path61)) {
|
|
27378
27554
|
try {
|
|
27379
|
-
content =
|
|
27555
|
+
content = readFileSync27(path61, "utf-8").trim();
|
|
27380
27556
|
} catch (e) {
|
|
27381
27557
|
console.warn(`[external-chan-rules] Failed to load: ${e}`);
|
|
27382
27558
|
}
|
|
@@ -27547,7 +27723,7 @@ ${text}` : text });
|
|
|
27547
27723
|
}
|
|
27548
27724
|
if (source === "user") {
|
|
27549
27725
|
try {
|
|
27550
|
-
const wm =
|
|
27726
|
+
const wm = readFileSync27(join37(workspace, ".work-mode"), "utf-8").trim();
|
|
27551
27727
|
if (wm === "on" && chatMode !== "work") {
|
|
27552
27728
|
chatMode = "work";
|
|
27553
27729
|
console.log(`[mode] ${sessionId} /work on \u2192 \u5F3A\u5236 work`);
|
|
@@ -27790,7 +27966,7 @@ ${text}` : text });
|
|
|
27790
27966
|
for (const memPath of newPaths) {
|
|
27791
27967
|
try {
|
|
27792
27968
|
const stat4 = statSync5(memPath);
|
|
27793
|
-
const content =
|
|
27969
|
+
const content = readFileSync27(memPath, "utf-8");
|
|
27794
27970
|
const header = memoryHeader(memPath, stat4.mtimeMs);
|
|
27795
27971
|
restoredMemories.push({ path: memPath, content, mtimeMs: stat4.mtimeMs, header });
|
|
27796
27972
|
} catch {
|
|
@@ -27877,7 +28053,7 @@ ${text}` : text });
|
|
|
27877
28053
|
const attachmentMemories = [];
|
|
27878
28054
|
for (const mem of relevantMemories) {
|
|
27879
28055
|
try {
|
|
27880
|
-
const content = mem.content ??
|
|
28056
|
+
const content = mem.content ?? readFileSync27(mem.path, "utf-8");
|
|
27881
28057
|
const header = mem.header ?? memoryHeader(mem.path, mem.mtimeMs);
|
|
27882
28058
|
attachmentMemories.push({ path: mem.path, content, mtimeMs: mem.mtimeMs, header });
|
|
27883
28059
|
} catch {
|
|
@@ -28197,7 +28373,7 @@ stack: ${err.stack ?? "(none)"}`);
|
|
|
28197
28373
|
}
|
|
28198
28374
|
} catch (err) {
|
|
28199
28375
|
try {
|
|
28200
|
-
(await import("node:fs")).appendFileSync(
|
|
28376
|
+
(await import("node:fs")).appendFileSync(join37(process.env.ENGINE7_STATE_DIR || path21.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7"), "logs", "autoDream-debug.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] [handle-query] autoDream trigger TRY-CATCH: ${err.message}
|
|
28201
28377
|
stack: ${err.stack ?? "(none)"}
|
|
28202
28378
|
`);
|
|
28203
28379
|
} catch {
|
|
@@ -34803,80 +34979,6 @@ ${inbound.content}` }, ...videoBlocks];
|
|
|
34803
34979
|
// src/optional/reporting/reporter.ts
|
|
34804
34980
|
init_live();
|
|
34805
34981
|
|
|
34806
|
-
// src/provision-free.ts
|
|
34807
|
-
import { randomBytes as randomBytes4, randomUUID as randomUUID6 } from "node:crypto";
|
|
34808
|
-
import { chmodSync, existsSync as existsSync24, mkdirSync as mkdirSync15, readFileSync as readFileSync34, writeFileSync as writeFileSync12 } from "node:fs";
|
|
34809
|
-
import { dirname as dirname12, join as join47 } from "node:path";
|
|
34810
|
-
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
34811
|
-
var __filename = fileURLToPath7(import.meta.url);
|
|
34812
|
-
var IDENTITY_FILE = "install-identity.json";
|
|
34813
|
-
function readContactEmailOf(parsed) {
|
|
34814
|
-
return typeof parsed?.contactEmail === "string" ? parsed.contactEmail.trim() : "";
|
|
34815
|
-
}
|
|
34816
|
-
function loadOrCreateInstallIdentity(stateDir) {
|
|
34817
|
-
const file2 = join47(stateDir, IDENTITY_FILE);
|
|
34818
|
-
if (existsSync24(file2)) {
|
|
34819
|
-
let parsed;
|
|
34820
|
-
try {
|
|
34821
|
-
parsed = JSON.parse(readFileSync34(file2, "utf8"));
|
|
34822
|
-
} catch (e) {
|
|
34823
|
-
throw new Error(
|
|
34824
|
-
`${IDENTITY_FILE} \u5B58\u5728\u4F46\u4E0D\u662F\u5408\u6CD5 JSON\uFF08${e.message}\uFF09\u2014\u2014\u5220\u6389\u5B83\u91CD\u8DD1\u4F1A\u9886\u4E00\u628A\u65B0\u4EE4\u724C\uFF0C\u65E7\u7684\u90A3\u628A\u53D6\u4E0D\u56DE\u6765`
|
|
34825
|
-
);
|
|
34826
|
-
}
|
|
34827
|
-
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
34828
|
-
throw new Error(`${IDENTITY_FILE} \u7F3A installId / installSecret \u5B57\u6BB5`);
|
|
34829
|
-
}
|
|
34830
|
-
const email = readContactEmailOf(parsed);
|
|
34831
|
-
return {
|
|
34832
|
-
installId: parsed.installId,
|
|
34833
|
-
installSecret: parsed.installSecret,
|
|
34834
|
-
...email ? { contactEmail: email } : {}
|
|
34835
|
-
};
|
|
34836
|
-
}
|
|
34837
|
-
const identity = {
|
|
34838
|
-
// 服务端校验 installId 长度为 8..36、只允许字母数字和连字符;uuid 正好符合
|
|
34839
|
-
installId: randomUUID6(),
|
|
34840
|
-
// 服务端校验 installSecret 为 32..64 位十六进制
|
|
34841
|
-
installSecret: randomBytes4(32).toString("hex")
|
|
34842
|
-
};
|
|
34843
|
-
mkdirSync15(stateDir, { recursive: true });
|
|
34844
|
-
writeFileSync12(file2, JSON.stringify(identity, null, 2) + "\n", { mode: 384 });
|
|
34845
|
-
try {
|
|
34846
|
-
chmodSync(file2, 384);
|
|
34847
|
-
} catch {
|
|
34848
|
-
}
|
|
34849
|
-
return identity;
|
|
34850
|
-
}
|
|
34851
|
-
function readInstallIdentityDetailed(stateDir) {
|
|
34852
|
-
const file2 = join47(stateDir, IDENTITY_FILE);
|
|
34853
|
-
if (!existsSync24(file2)) return { ok: false, reason: "missing" };
|
|
34854
|
-
let text;
|
|
34855
|
-
try {
|
|
34856
|
-
text = readFileSync34(file2, "utf8");
|
|
34857
|
-
} catch (e) {
|
|
34858
|
-
return { ok: false, reason: "corrupt", detail: `\u5B58\u5728\u4F46\u8BFB\u4E0D\u4E86\uFF08${e?.message ?? e}\uFF09` };
|
|
34859
|
-
}
|
|
34860
|
-
let parsed;
|
|
34861
|
-
try {
|
|
34862
|
-
parsed = JSON.parse(text);
|
|
34863
|
-
} catch (e) {
|
|
34864
|
-
return { ok: false, reason: "corrupt", detail: `\u4E0D\u662F\u5408\u6CD5 JSON\uFF08${e?.message ?? e}\uFF09` };
|
|
34865
|
-
}
|
|
34866
|
-
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
34867
|
-
return { ok: false, reason: "corrupt", detail: "\u7F3A installId / installSecret \u5B57\u6BB5" };
|
|
34868
|
-
}
|
|
34869
|
-
const email = readContactEmailOf(parsed);
|
|
34870
|
-
return {
|
|
34871
|
-
ok: true,
|
|
34872
|
-
identity: {
|
|
34873
|
-
installId: parsed.installId,
|
|
34874
|
-
installSecret: parsed.installSecret,
|
|
34875
|
-
...email ? { contactEmail: email } : {}
|
|
34876
|
-
}
|
|
34877
|
-
};
|
|
34878
|
-
}
|
|
34879
|
-
|
|
34880
34982
|
// src/optional/reporting/state.ts
|
|
34881
34983
|
import { existsSync as existsSync25, mkdirSync as mkdirSync16, readFileSync as readFileSync35, writeFileSync as writeFileSync13 } from "node:fs";
|
|
34882
34984
|
import { join as join48 } from "node:path";
|
|
@@ -35744,6 +35846,21 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
35744
35846
|
}
|
|
35745
35847
|
}
|
|
35746
35848
|
}
|
|
35849
|
+
/**
|
|
35850
|
+
* 检查飞书 API 的**业务返回码**(1001)。
|
|
35851
|
+
*
|
|
35852
|
+
* SDK 只在 **HTTP 非 2xx** 时抛错;业务错误走的是 "HTTP 200 + code≠0" —— 不查码就等于把
|
|
35853
|
+
* "飞书拒了"读成"发出去了"。客户那台 mac 的语音条"日志 Voice sent!、人没收到"卡了一整天
|
|
35854
|
+
* 就是卡在这儿:**引擎从不看码,所以线上到底是发成功了还是被拒了,日志里一个字都没有**。
|
|
35855
|
+
* (1001 实测:同一套参数在我方租户 code:0 全绿,把时长/内容形状/chat_id 通道三项嫌疑逐条排除,
|
|
35856
|
+
* 嫌疑因此全部落到"客户租户返回了什么"上——而那个答案以前根本打印不出来。)
|
|
35857
|
+
*/
|
|
35858
|
+
_assertApiOk(res, what) {
|
|
35859
|
+
const code = res?.code;
|
|
35860
|
+
if (typeof code === "number" && code !== 0) {
|
|
35861
|
+
throw new Error(`Feishu ${what} \u88AB\u62D2: code=${code} msg=${res?.msg ?? ""}\uFF08HTTP 2xx \u4E5F\u53EF\u80FD\u662F\u4E1A\u52A1\u9519\u8BEF\u2014\u2014\u8FD9\u6B63\u662F\u300C\u62A5\u6210\u529F\u5374\u6CA1\u5230\u300D\u90A3\u7C7B\uFF09`);
|
|
35862
|
+
}
|
|
35863
|
+
}
|
|
35747
35864
|
/** 发送媒体附件(图片/文件) */
|
|
35748
35865
|
async sendFile(target, message, attachment) {
|
|
35749
35866
|
const fs60 = await import("node:fs");
|
|
@@ -35761,25 +35878,25 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
35761
35878
|
const imageKey = await this._uploadImage(fileBuffer, filename);
|
|
35762
35879
|
if (message) {
|
|
35763
35880
|
const postContent = this._buildImagePost(message, imageKey);
|
|
35764
|
-
await this.client.im.message.create({
|
|
35881
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
35765
35882
|
params: { receive_id_type: receiveIdType },
|
|
35766
35883
|
data: { receive_id: safeTarget, msg_type: "post", content: JSON.stringify(postContent) }
|
|
35767
|
-
});
|
|
35884
|
+
}), "\u56FE\u7247\u6D88\u606F\u53D1\u9001");
|
|
35768
35885
|
} else {
|
|
35769
|
-
await this.client.im.message.create({
|
|
35886
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
35770
35887
|
params: { receive_id_type: receiveIdType },
|
|
35771
35888
|
data: { receive_id: safeTarget, msg_type: "image", content: JSON.stringify({ image_key: imageKey }) }
|
|
35772
|
-
});
|
|
35889
|
+
}), "\u56FE\u7247\u6D88\u606F\u53D1\u9001");
|
|
35773
35890
|
}
|
|
35774
35891
|
} else if (mimeType.startsWith("audio/")) {
|
|
35775
35892
|
const isOpus = filename.endsWith(".opus") || filename.endsWith(".ogg") || mimeType === "audio/opus";
|
|
35776
35893
|
if (!isOpus) {
|
|
35777
35894
|
console.warn(`[feishu:sendFile] audio '${filename}' \u4E0D\u662Fopus\uFF0C\u964D\u7EA7\u4E3A\u6587\u4EF6\u6D88\u606F\uFF08\u975E\u8BED\u97F3\u6761\uFF09`);
|
|
35778
35895
|
const fileKey = await this._uploadFile(fileBuffer, filename);
|
|
35779
|
-
await this.client.im.message.create({
|
|
35896
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
35780
35897
|
params: { receive_id_type: receiveIdType },
|
|
35781
35898
|
data: { receive_id: safeTarget, msg_type: "file", content: JSON.stringify({ file_key: fileKey }) }
|
|
35782
|
-
});
|
|
35899
|
+
}), "\u6587\u4EF6\u6D88\u606F\u53D1\u9001\uFF08\u975E opus \u97F3\u9891\u964D\u7EA7\uFF09");
|
|
35783
35900
|
} else {
|
|
35784
35901
|
let durationMs = Math.round(fileBuffer.length / 3);
|
|
35785
35902
|
try {
|
|
@@ -35792,17 +35909,17 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
35792
35909
|
} catch {
|
|
35793
35910
|
}
|
|
35794
35911
|
const audioKey = await this._uploadAudio(fileBuffer, filename.endsWith(".opus") ? filename : filename.replace(/\.[^.]+$/, ".opus"), durationMs);
|
|
35795
|
-
await this.client.im.message.create({
|
|
35912
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
35796
35913
|
params: { receive_id_type: receiveIdType },
|
|
35797
35914
|
data: { receive_id: safeTarget, msg_type: "audio", content: JSON.stringify({ file_key: audioKey }) }
|
|
35798
|
-
});
|
|
35915
|
+
}), "\u8BED\u97F3\u6761\u53D1\u9001");
|
|
35799
35916
|
}
|
|
35800
35917
|
} else {
|
|
35801
35918
|
const fileKey = await this._uploadFile(fileBuffer, filename);
|
|
35802
|
-
await this.client.im.message.create({
|
|
35919
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
35803
35920
|
params: { receive_id_type: receiveIdType },
|
|
35804
35921
|
data: { receive_id: safeTarget, msg_type: "file", content: JSON.stringify({ file_key: fileKey }) }
|
|
35805
|
-
});
|
|
35922
|
+
}), "\u6587\u4EF6\u6D88\u606F\u53D1\u9001");
|
|
35806
35923
|
}
|
|
35807
35924
|
if (message && mimeType.startsWith("image/")) {
|
|
35808
35925
|
} else if (message) {
|
|
@@ -40960,7 +41077,7 @@ var TTS_IMPL = {
|
|
|
40960
41077
|
if (r.warning) console.warn(`[my-voice] ${r.warning}`);
|
|
40961
41078
|
if (!r.voice) {
|
|
40962
41079
|
throw new TtsConfigError(
|
|
40963
|
-
"relay TTS \u7F3A\u97F3\u8272\uFF1Atools.my_voice.voice \u662F\u7A7A\u7684\uFF0C\u4E0A\u6E38\u4F1A\u62D2\u3002\u514D\u8D39\u6863\u88C5\u673A\u5E94\u5DF2\
|
|
41080
|
+
"relay TTS \u7F3A\u97F3\u8272\uFF1Atools.my_voice.voice \u662F\u7A7A\u7684\uFF0C\u4E0A\u6E38\u4F1A\u62D2\u3002\u514D\u8D39\u6863\u88C5\u673A\u5E94\u5DF2\u81EA\u52A8\u586B\u597D\u9ED8\u8BA4\u97F3\u8272\uFF08\u65B0\u88C5\u673A generateConfig / \u8001\u88C5\u673A\u542F\u52A8\u8865\u9F50 / \u5207\u6362\u514D\u8D39\u6863 applyFreeTier \u4E09\u6761\u8DEF\uFF0C\u89C1 cli-init-config.ts \u7684 freeTierVoiceConfig\uFF09\u3002"
|
|
40964
41081
|
);
|
|
40965
41082
|
}
|
|
40966
41083
|
try {
|
|
@@ -41183,7 +41300,7 @@ registry.register({
|
|
|
41183
41300
|
description: "TTS engine. relay = 7yi \u4E2D\u8F6C\u7AD9\uFF08\u514D\u8D39\u6863\u9ED8\u8BA4\uFF09\uFF0Ccosyvoice = \u767E\u70BC API\uFF0Cgptsovits = \u672C\u5730\u514B\u9686\uFF0Cqwen3-3060 = \u672C\u5730 GGML\uFF0Cedge = \u515C\u5E95\u3002"
|
|
41184
41301
|
},
|
|
41185
41302
|
channel: { type: "string", enum: ["weixin", "feishu", "discord"], description: "Target channel. Default: current channel." },
|
|
41186
|
-
to: { type: "string", description:
|
|
41303
|
+
to: { type: "string", description: 'Recipient ID, ONLY when sending to someone else. \u5FAE\u4FE1\u683C\u5F0F o\u5F00\u5934@im.wechat\u7ED3\u5C3E\uFF0C\u98DE\u4E66\u683C\u5F0F ou_\u5F00\u5934 open_id\uFF1B\u53D1\u7ED9\u522B\u4EBA\u524D read prompts/contacts.md \u67E5\u6536\u4EF6\u4EBA ID\u3002**\u53D1\u7ED9\u5F53\u524D\u5BF9\u8BDD\u7684\u4EBA\uFF08"\u53D1\u7ED9\u6211/\u53D1\u6761\u8BED\u97F3"\uFF09\u4E0D\u8981\u586B to**\u2014\u2014\u7559\u7A7A\u5373\u53D1\u5F53\u524D\u4F1A\u8BDD\uFF0C\u8FD9\u662F\u9ED8\u8BA4\u4E5F\u662F\u66F4\u7A33\u7684\u8DEF\uFF08\u90E8\u5206\u79DF\u6237\u4F1A\u62D2"\u6309\u7528\u6237 ID \u76F4\u53D1"\uFF0C\u89C1 1001 \u6848\u4F8B\uFF09\u3002multaca \u4EFB\u52A1\u91CC\u4E0D\u9700\u8981\u586B to\u2014\u2014\u8BED\u97F3\u4F1A\u6302\u5230\u5F53\u524D issue \u8BC4\u8BBA\uFF0C\u586B issueId \u6307\u5B9A\u76EE\u6807 issue\u3002' },
|
|
41187
41304
|
issueId: { type: "string", description: 'multaca headless \u4E13\u7528\uFF1A\u76EE\u6807 issue ID\uFF08\u4EFB\u52A1 prompt \u91CC\u7684 "Your assigned issue ID"\uFF09\u3002\u666E\u901A\u98DE\u4E66/\u5FAE\u4FE1\u573A\u666F\u4E0D\u8981\u586B\u3002' },
|
|
41188
41305
|
caption: { type: "string", description: "Optional text to accompany the voice message." }
|
|
41189
41306
|
},
|
|
@@ -41295,7 +41412,8 @@ registry.register({
|
|
|
41295
41412
|
}
|
|
41296
41413
|
return { content: `Voice sent! (${actualEngine}, ${sizeKB.toFixed(0)}KB, ${resolvedChannel})` };
|
|
41297
41414
|
} catch (err) {
|
|
41298
|
-
|
|
41415
|
+
const toHint = args.to ? '\u3002\u26A0\uFE0F \u8FD9\u6B21\u5E26\u7684\u662F to=\u6536\u4EF6\u4EBA ID\uFF1A\u82E5\u6536\u4EF6\u4EBA\u5C31\u662F**\u5F53\u524D\u5BF9\u8BDD\u7684\u4EBA**\uFF0C\u53BB\u6389 to \u91CD\u8BD5\u2014\u2014\u5F15\u64CE\u4F1A\u53D1\u7ED9\u5F53\u524D\u4F1A\u8BDD\uFF0C\u90E8\u5206\u79DF\u6237\u4F1A\u62D2"\u6309\u7528\u6237 ID \u76F4\u53D1"\uFF08\u98DE\u4E66 230101\uFF09' : "";
|
|
41416
|
+
return { content: `Voice send failed: ${err.message}${toHint}`, isError: true };
|
|
41299
41417
|
}
|
|
41300
41418
|
},
|
|
41301
41419
|
isConcurrencySafe: () => false,
|
|
@@ -44834,6 +44952,7 @@ async function startEngine(config, opts) {
|
|
|
44834
44952
|
applyFreeTierVideoFixup({ all: () => liveConfig.all(), set: (p, v) => {
|
|
44835
44953
|
void liveConfig.set(p, v);
|
|
44836
44954
|
} });
|
|
44955
|
+
await applyFreeTierVoiceFixup({ all: () => liveConfig.all(), set: (p, v) => liveConfig.set(p, v) });
|
|
44837
44956
|
let provider;
|
|
44838
44957
|
let visionProvider;
|
|
44839
44958
|
let visionChainLabels;
|