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/main.mjs
CHANGED
|
@@ -124,6 +124,17 @@ var init_live = __esm({
|
|
|
124
124
|
Object.assign(this.current, newConfig);
|
|
125
125
|
}
|
|
126
126
|
/** 改活树上的值;文件承载路径同步持久化(read-modify-write 回 config 文件) */
|
|
127
|
+
/**
|
|
128
|
+
* 改活树 + 落盘。
|
|
129
|
+
*
|
|
130
|
+
* 返回值 = **落盘**是否成功(活树无论成败都已同步——它是先改的)。绝大多数调用点照旧
|
|
131
|
+
* `void liveConfig.set(...)` 不理它;但**要打成功日志的调用点必须 await 这个布尔值**。
|
|
132
|
+
*
|
|
133
|
+
* 为什么把这个信号交出去(1001 审查捞回):本方法本来是 fire-and-forget,落盘失败只在
|
|
134
|
+
* `persistToFile` 里 warn 一行;而启动早段的调用点(两个免费档 fixup)紧接着打了句
|
|
135
|
+
* "免费档补齐 xxx" 的成功日志 ⇒ 配置**没写进文件**却被读成"写好了":进程内生效、托盘
|
|
136
|
+
* 读文件还是旧值、下次启动重放同一句——正是本仓最恨的假信号。
|
|
137
|
+
*/
|
|
127
138
|
async set(dotPath, val) {
|
|
128
139
|
if (!this.current) throw new Error("[liveConfig] not initialized \u2014 call liveConfig.init() first");
|
|
129
140
|
const keys = dotPath.split(".");
|
|
@@ -133,15 +144,15 @@ var init_live = __esm({
|
|
|
133
144
|
obj = obj[keys[i]];
|
|
134
145
|
}
|
|
135
146
|
obj[keys[keys.length - 1]] = val;
|
|
136
|
-
|
|
147
|
+
return this.persistToFile(dotPath, val);
|
|
137
148
|
}
|
|
138
|
-
/** 把改动写回 config
|
|
149
|
+
/** 把改动写回 config 文件对应段(找不到文件路径则只内存生效)。返回是否真的落盘。 */
|
|
139
150
|
async persistToFile(dotPath, val) {
|
|
140
151
|
const fs60 = await import("node:fs");
|
|
141
152
|
const cfgPath = this.current?._configFilePath;
|
|
142
153
|
if (!cfgPath || !fs60.existsSync(cfgPath)) {
|
|
143
154
|
console.warn(`[liveConfig] set: no config file path, in-memory only (${dotPath})`);
|
|
144
|
-
return;
|
|
155
|
+
return false;
|
|
145
156
|
}
|
|
146
157
|
try {
|
|
147
158
|
const raw = JSON.parse(fs60.readFileSync(cfgPath, "utf-8"));
|
|
@@ -155,8 +166,10 @@ var init_live = __esm({
|
|
|
155
166
|
fs60.writeFileSync(cfgPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
|
|
156
167
|
console.log(`[liveConfig] persisted ${dotPath} = ${JSON.stringify(val)} to ${cfgPath}`);
|
|
157
168
|
markSelfWrite();
|
|
169
|
+
return true;
|
|
158
170
|
} catch (e) {
|
|
159
171
|
console.warn(`[liveConfig] persist failed (${dotPath}): ${e.message}`);
|
|
172
|
+
return false;
|
|
160
173
|
}
|
|
161
174
|
}
|
|
162
175
|
/** 是否已初始化 */
|
|
@@ -8310,30 +8323,30 @@ __export(teamHelpers_exports, {
|
|
|
8310
8323
|
writeTeamFile: () => writeTeamFile,
|
|
8311
8324
|
writeTeamFileAsync: () => writeTeamFileAsync
|
|
8312
8325
|
});
|
|
8313
|
-
import { mkdirSync as
|
|
8326
|
+
import { mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync6 } from "node:fs";
|
|
8314
8327
|
import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
|
|
8315
|
-
import { join as
|
|
8328
|
+
import { join as join17 } from "node:path";
|
|
8316
8329
|
function initTeamDirs(stateDir) {
|
|
8317
8330
|
_stateDir = stateDir;
|
|
8318
8331
|
}
|
|
8319
8332
|
function getTeamsDir() {
|
|
8320
|
-
return
|
|
8333
|
+
return join17(_stateDir, "teams");
|
|
8321
8334
|
}
|
|
8322
8335
|
function getTasksDir() {
|
|
8323
|
-
return
|
|
8336
|
+
return join17(_stateDir, "tasks");
|
|
8324
8337
|
}
|
|
8325
8338
|
function sanitizeName(name) {
|
|
8326
8339
|
return name.replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase();
|
|
8327
8340
|
}
|
|
8328
8341
|
function getTeamDir(teamName) {
|
|
8329
|
-
return
|
|
8342
|
+
return join17(getTeamsDir(), sanitizeName(teamName));
|
|
8330
8343
|
}
|
|
8331
8344
|
function getTeamFilePath(teamName) {
|
|
8332
|
-
return
|
|
8345
|
+
return join17(getTeamDir(teamName), "config.json");
|
|
8333
8346
|
}
|
|
8334
8347
|
function readTeamFile(teamName) {
|
|
8335
8348
|
try {
|
|
8336
|
-
const content =
|
|
8349
|
+
const content = readFileSync12(getTeamFilePath(teamName), "utf-8");
|
|
8337
8350
|
return JSON.parse(content);
|
|
8338
8351
|
} catch (e) {
|
|
8339
8352
|
if (e?.code === "ENOENT") return null;
|
|
@@ -8353,8 +8366,8 @@ async function readTeamFileAsync(teamName) {
|
|
|
8353
8366
|
}
|
|
8354
8367
|
function writeTeamFile(teamName, teamFile) {
|
|
8355
8368
|
const teamDir = getTeamDir(teamName);
|
|
8356
|
-
|
|
8357
|
-
|
|
8369
|
+
mkdirSync9(teamDir, { recursive: true });
|
|
8370
|
+
writeFileSync6(getTeamFilePath(teamName), JSON.stringify(teamFile, null, 2));
|
|
8358
8371
|
}
|
|
8359
8372
|
async function writeTeamFileAsync(teamName, teamFile) {
|
|
8360
8373
|
const teamDir = getTeamDir(teamName);
|
|
@@ -8434,7 +8447,7 @@ async function cleanupTeamDirectories(teamName) {
|
|
|
8434
8447
|
} catch (error) {
|
|
8435
8448
|
console.warn(`[teamHelpers] Failed to clean up team directory ${teamDir}: ${error.message}`);
|
|
8436
8449
|
}
|
|
8437
|
-
const tasksDir =
|
|
8450
|
+
const tasksDir = join17(getTasksDir(), sanitizedName);
|
|
8438
8451
|
try {
|
|
8439
8452
|
await rm(tasksDir, { recursive: true, force: true });
|
|
8440
8453
|
console.log(`[teamHelpers] Cleaned up tasks directory: ${tasksDir}`);
|
|
@@ -8443,8 +8456,8 @@ async function cleanupTeamDirectories(teamName) {
|
|
|
8443
8456
|
}
|
|
8444
8457
|
}
|
|
8445
8458
|
function ensureTasksDir(taskListId) {
|
|
8446
|
-
const dir =
|
|
8447
|
-
|
|
8459
|
+
const dir = join17(getTasksDir(), taskListId);
|
|
8460
|
+
mkdirSync9(dir, { recursive: true });
|
|
8448
8461
|
}
|
|
8449
8462
|
function setLeaderTeamName(name) {
|
|
8450
8463
|
_leaderTeamName = name;
|
|
@@ -8489,9 +8502,9 @@ __export(teammateMailbox_exports, {
|
|
|
8489
8502
|
writeToMailbox: () => writeToMailbox
|
|
8490
8503
|
});
|
|
8491
8504
|
import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
|
|
8492
|
-
import { join as
|
|
8505
|
+
import { join as join18 } from "node:path";
|
|
8493
8506
|
function getTeamsDir2() {
|
|
8494
|
-
return
|
|
8507
|
+
return join18(process.env.ENGINE_STATE_DIR || ".", "teams");
|
|
8495
8508
|
}
|
|
8496
8509
|
function sanitizePathComponent(s) {
|
|
8497
8510
|
return s.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
@@ -8500,12 +8513,12 @@ function getInboxPath(agentName, teamName) {
|
|
|
8500
8513
|
const team = teamName || "default";
|
|
8501
8514
|
const safeTeam = sanitizePathComponent(team);
|
|
8502
8515
|
const safeAgentName = sanitizePathComponent(agentName);
|
|
8503
|
-
return
|
|
8516
|
+
return join18(getTeamsDir2(), safeTeam, "inboxes", `${safeAgentName}.json`);
|
|
8504
8517
|
}
|
|
8505
8518
|
async function ensureInboxDir(teamName) {
|
|
8506
8519
|
const team = teamName || "default";
|
|
8507
8520
|
const safeTeam = sanitizePathComponent(team);
|
|
8508
|
-
const inboxDir =
|
|
8521
|
+
const inboxDir = join18(getTeamsDir2(), safeTeam, "inboxes");
|
|
8509
8522
|
await mkdir2(inboxDir, { recursive: true });
|
|
8510
8523
|
}
|
|
8511
8524
|
async function sleep2(ms) {
|
|
@@ -8814,7 +8827,7 @@ var init_inboxPoller = __esm({
|
|
|
8814
8827
|
|
|
8815
8828
|
// src/memory/memdir/memoryScan.ts
|
|
8816
8829
|
import { readdir, stat as stat2, readFile as readFile3 } from "node:fs/promises";
|
|
8817
|
-
import { basename as basename4, join as
|
|
8830
|
+
import { basename as basename4, join as join19, sep as sep3 } from "node:path";
|
|
8818
8831
|
function isArchivedPath(relativePath) {
|
|
8819
8832
|
return relativePath.split(sep3).includes("archive");
|
|
8820
8833
|
}
|
|
@@ -8864,7 +8877,7 @@ async function scanMemoryFiles2(memoryDir, signal, maxFiles) {
|
|
|
8864
8877
|
);
|
|
8865
8878
|
const headerResults = await Promise.allSettled(
|
|
8866
8879
|
mdFiles.map(async (relativePath) => {
|
|
8867
|
-
const filePath =
|
|
8880
|
+
const filePath = join19(memoryDir, relativePath);
|
|
8868
8881
|
const { content, mtimeMs } = await readFileHeader(
|
|
8869
8882
|
filePath,
|
|
8870
8883
|
FRONTMATTER_MAX_LINES,
|
|
@@ -9798,8 +9811,8 @@ var init_filters = __esm({
|
|
|
9798
9811
|
|
|
9799
9812
|
// src/mem7/core/vector-store.ts
|
|
9800
9813
|
import { Schema, Field, Utf8, Float32, Int64, FixedSizeList, TimestampMicrosecond, List } from "apache-arrow";
|
|
9801
|
-
import { mkdirSync as
|
|
9802
|
-
import { join as
|
|
9814
|
+
import { mkdirSync as mkdirSync10 } from "node:fs";
|
|
9815
|
+
import { join as join24 } from "node:path";
|
|
9803
9816
|
function lanceSpecifierFor(platform2, arch) {
|
|
9804
9817
|
return platform2 === "darwin" && arch === "x64" ? "@engine7/lancedb-intel" : "@lancedb/lancedb";
|
|
9805
9818
|
}
|
|
@@ -9895,13 +9908,13 @@ var init_vector_store = __esm({
|
|
|
9895
9908
|
dir;
|
|
9896
9909
|
tables = /* @__PURE__ */ new Map();
|
|
9897
9910
|
constructor(stateDir) {
|
|
9898
|
-
this.dir =
|
|
9911
|
+
this.dir = join24(mem7Root(stateDir), "index", "lancedb");
|
|
9899
9912
|
}
|
|
9900
9913
|
async conn() {
|
|
9901
9914
|
if (!this.db) {
|
|
9902
9915
|
const lance = await loadLance();
|
|
9903
9916
|
if (!lance) throw new Mem7VectorUnavailableError();
|
|
9904
|
-
|
|
9917
|
+
mkdirSync10(this.dir, { recursive: true });
|
|
9905
9918
|
this.db = await lance.connect(this.dir);
|
|
9906
9919
|
}
|
|
9907
9920
|
return this.db;
|
|
@@ -10190,14 +10203,14 @@ Follow these principles when generating episodic memories:
|
|
|
10190
10203
|
|
|
10191
10204
|
// src/mem7/core/store.ts
|
|
10192
10205
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
10193
|
-
import { mkdirSync as
|
|
10194
|
-
import { join as
|
|
10206
|
+
import { mkdirSync as mkdirSync11, readFileSync as readFileSync17, writeFileSync as writeFileSync8, existsSync as existsSync17, readdirSync as readdirSync2 } from "node:fs";
|
|
10207
|
+
import { join as join25 } from "node:path";
|
|
10195
10208
|
import { createHash as createHash2 } from "node:crypto";
|
|
10196
10209
|
function contentHash(text) {
|
|
10197
10210
|
return createHash2("sha256").update(text.replace(/\s+/g, "")).digest("hex").slice(0, 40);
|
|
10198
10211
|
}
|
|
10199
10212
|
function mem7Root(stateDir) {
|
|
10200
|
-
return
|
|
10213
|
+
return join25(stateDir, "mem7");
|
|
10201
10214
|
}
|
|
10202
10215
|
var SCHEMA, Mem7Store;
|
|
10203
10216
|
var init_store2 = __esm({
|
|
@@ -10233,8 +10246,8 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10233
10246
|
constructor(stateDir) {
|
|
10234
10247
|
this.stateDir = stateDir;
|
|
10235
10248
|
this.root = mem7Root(stateDir);
|
|
10236
|
-
|
|
10237
|
-
this.db = new DatabaseSync2(
|
|
10249
|
+
mkdirSync11(join25(this.root, "index"), { recursive: true });
|
|
10250
|
+
this.db = new DatabaseSync2(join25(this.root, "index", "mem7.db"));
|
|
10238
10251
|
this.db.exec("PRAGMA journal_mode=WAL");
|
|
10239
10252
|
this.db.exec(SCHEMA);
|
|
10240
10253
|
}
|
|
@@ -10365,14 +10378,14 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10365
10378
|
/** md 追加通用:frontmatter(存在则更新计数)+ 既有 entry 块全保留 + 追加新块 */
|
|
10366
10379
|
appendMd(ownerId, dirName, filePrefix, type2, dateStr, entries2, render) {
|
|
10367
10380
|
if (entries2.length === 0) return;
|
|
10368
|
-
const dir =
|
|
10369
|
-
|
|
10370
|
-
const file2 =
|
|
10381
|
+
const dir = join25(this.root, "users", ownerId, dirName);
|
|
10382
|
+
mkdirSync11(dir, { recursive: true });
|
|
10383
|
+
const file2 = join25(dir, `${filePrefix}-${dateStr}.md`);
|
|
10371
10384
|
let head;
|
|
10372
10385
|
let existingBlocks = "";
|
|
10373
10386
|
let count;
|
|
10374
|
-
if (
|
|
10375
|
-
const text =
|
|
10387
|
+
if (existsSync17(file2)) {
|
|
10388
|
+
const text = readFileSync17(file2, "utf8");
|
|
10376
10389
|
const fmEnd = text.indexOf("\n---", 3);
|
|
10377
10390
|
const split = fmEnd >= 0 ? fmEnd + 4 : text.length;
|
|
10378
10391
|
head = text.slice(0, split);
|
|
@@ -10403,7 +10416,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10403
10416
|
count++;
|
|
10404
10417
|
}
|
|
10405
10418
|
head = head.replace(/entry_count: \d+/, `entry_count: ${count}`).replace(/last_appended_at: '[^']*'/, `last_appended_at: '${formatMdTimestamp()}'`);
|
|
10406
|
-
|
|
10419
|
+
writeFileSync8(file2, head + "\n\n" + blocks.join("\n\n") + "\n", "utf8");
|
|
10407
10420
|
}
|
|
10408
10421
|
/**
|
|
10409
10422
|
* entry_id:前缀_YYYYMMDD_六位序号。
|
|
@@ -10423,11 +10436,11 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10423
10436
|
af: [".atomic_facts", "atomic-facts"]
|
|
10424
10437
|
};
|
|
10425
10438
|
const [dirName, filePrefix] = dirByPrefix[prefix];
|
|
10426
|
-
const file2 =
|
|
10439
|
+
const file2 = join25(this.root, "users", ownerId, dirName, `${filePrefix}-${dateStr}.md`);
|
|
10427
10440
|
let max = 0;
|
|
10428
|
-
if (
|
|
10441
|
+
if (existsSync17(file2)) {
|
|
10429
10442
|
const re = new RegExp(`${prefix}_${dateStr.replace(/-/g, "")}_(\\d+)`, "g");
|
|
10430
|
-
for (const m of
|
|
10443
|
+
for (const m of readFileSync17(file2, "utf8").matchAll(re)) max = Math.max(max, Number(m[1]));
|
|
10431
10444
|
}
|
|
10432
10445
|
return max;
|
|
10433
10446
|
}
|
|
@@ -10494,17 +10507,17 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
10494
10507
|
getOpenPredictions(now, limit = 50) {
|
|
10495
10508
|
const today3 = todayKey(now);
|
|
10496
10509
|
const out = [];
|
|
10497
|
-
const usersDir =
|
|
10498
|
-
if (!
|
|
10510
|
+
const usersDir = join25(this.root, "users");
|
|
10511
|
+
if (!existsSync17(usersDir)) return out;
|
|
10499
10512
|
for (const owner of readdirSync2(usersDir, { withFileTypes: true })) {
|
|
10500
10513
|
if (!owner.isDirectory()) continue;
|
|
10501
|
-
const dir =
|
|
10502
|
-
if (!
|
|
10514
|
+
const dir = join25(usersDir, owner.name, ".foresights");
|
|
10515
|
+
if (!existsSync17(dir)) continue;
|
|
10503
10516
|
for (const f of readdirSync2(dir)) {
|
|
10504
10517
|
if (!/^foresight-\d{4}-\d{2}-\d{2}\.md$/.test(f)) continue;
|
|
10505
10518
|
let content;
|
|
10506
10519
|
try {
|
|
10507
|
-
content =
|
|
10520
|
+
content = readFileSync17(join25(dir, f), "utf8");
|
|
10508
10521
|
} catch {
|
|
10509
10522
|
continue;
|
|
10510
10523
|
}
|
|
@@ -10583,9 +10596,9 @@ var init_ingest2 = __esm({
|
|
|
10583
10596
|
});
|
|
10584
10597
|
|
|
10585
10598
|
// src/mem7/core/ids.ts
|
|
10586
|
-
import { randomBytes as
|
|
10599
|
+
import { randomBytes as randomBytes4 } from "node:crypto";
|
|
10587
10600
|
function hex(len) {
|
|
10588
|
-
return
|
|
10601
|
+
return randomBytes4(Math.ceil(len / 2)).toString("hex").slice(0, len);
|
|
10589
10602
|
}
|
|
10590
10603
|
function randomCellId() {
|
|
10591
10604
|
return `mc_${hex(12)}`;
|
|
@@ -10597,9 +10610,9 @@ var init_ids = __esm({
|
|
|
10597
10610
|
});
|
|
10598
10611
|
|
|
10599
10612
|
// src/mem7/core/boundary.ts
|
|
10600
|
-
import { readFileSync as
|
|
10601
|
-
import { join as
|
|
10602
|
-
import { fileURLToPath as
|
|
10613
|
+
import { readFileSync as readFileSync18 } from "node:fs";
|
|
10614
|
+
import { join as join26, dirname as dirname5 } from "node:path";
|
|
10615
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
10603
10616
|
function renderBoundaryInput(messages) {
|
|
10604
10617
|
return messages.map((m, i) => `[${i + 1}] [${new Date(m.tsMs).toISOString()}] ${m.senderName ?? m.senderId}: ${m.text}`).join("\n");
|
|
10605
10618
|
}
|
|
@@ -10692,14 +10705,14 @@ var init_boundary = __esm({
|
|
|
10692
10705
|
HARD_TOKEN_LIMIT = 8192;
|
|
10693
10706
|
HARD_MSG_LIMIT = 50;
|
|
10694
10707
|
RETRIES = 3;
|
|
10695
|
-
PROMPT2 =
|
|
10708
|
+
PROMPT2 = readFileSync18(join26(dirname5(fileURLToPath3(import.meta.url)), "prompts", "boundary.md"), "utf8");
|
|
10696
10709
|
}
|
|
10697
10710
|
});
|
|
10698
10711
|
|
|
10699
10712
|
// src/mem7/core/episode.ts
|
|
10700
|
-
import { readFileSync as
|
|
10701
|
-
import { join as
|
|
10702
|
-
import { fileURLToPath as
|
|
10713
|
+
import { readFileSync as readFileSync19 } from "node:fs";
|
|
10714
|
+
import { join as join27, dirname as dirname6 } from "node:path";
|
|
10715
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
10703
10716
|
function renderConversation(cell) {
|
|
10704
10717
|
return cell.messages.map((m) => `
|
|
10705
10718
|
{
|
|
@@ -10755,14 +10768,14 @@ var init_episode = __esm({
|
|
|
10755
10768
|
"use strict";
|
|
10756
10769
|
init_prompt_render();
|
|
10757
10770
|
RETRIES2 = 2;
|
|
10758
|
-
PROMPT3 =
|
|
10771
|
+
PROMPT3 = readFileSync19(join27(dirname6(fileURLToPath4(import.meta.url)), "prompts", "episode.md"), "utf8");
|
|
10759
10772
|
}
|
|
10760
10773
|
});
|
|
10761
10774
|
|
|
10762
10775
|
// src/mem7/core/atomic-facts.ts
|
|
10763
|
-
import { readFileSync as
|
|
10764
|
-
import { join as
|
|
10765
|
-
import { fileURLToPath as
|
|
10776
|
+
import { readFileSync as readFileSync20 } from "node:fs";
|
|
10777
|
+
import { join as join28, dirname as dirname7 } from "node:path";
|
|
10778
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
10766
10779
|
async function extractAtomicFacts(cell, provider, model) {
|
|
10767
10780
|
const userPrompt = renderPrompt(PROMPT4, {
|
|
10768
10781
|
INPUT_TEXT: renderConversationText(cell.messages),
|
|
@@ -10797,14 +10810,14 @@ var init_atomic_facts = __esm({
|
|
|
10797
10810
|
init_episode();
|
|
10798
10811
|
init_prompt_render();
|
|
10799
10812
|
RETRIES3 = 5;
|
|
10800
|
-
PROMPT4 =
|
|
10813
|
+
PROMPT4 = readFileSync20(join28(dirname7(fileURLToPath5(import.meta.url)), "prompts", "atomic-facts-memcell.md"), "utf8");
|
|
10801
10814
|
}
|
|
10802
10815
|
});
|
|
10803
10816
|
|
|
10804
10817
|
// src/mem7/core/foresight.ts
|
|
10805
|
-
import { readFileSync as
|
|
10806
|
-
import { join as
|
|
10807
|
-
import { fileURLToPath as
|
|
10818
|
+
import { readFileSync as readFileSync21 } from "node:fs";
|
|
10819
|
+
import { join as join29, dirname as dirname8 } from "node:path";
|
|
10820
|
+
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
10808
10821
|
function cleanDateString(dateStr) {
|
|
10809
10822
|
if (typeof dateStr !== "string" || !dateStr) return null;
|
|
10810
10823
|
const cleaned = dateStr.replace(/[^\d-]/g, "");
|
|
@@ -10887,7 +10900,7 @@ var init_foresight = __esm({
|
|
|
10887
10900
|
MAX_COUNT = 10;
|
|
10888
10901
|
MIN_COUNT = 4;
|
|
10889
10902
|
TEMPERATURE = 0.3;
|
|
10890
|
-
PROMPT5 =
|
|
10903
|
+
PROMPT5 = readFileSync21(join29(dirname8(fileURLToPath6(import.meta.url)), "prompts", "foresight.md"), "utf8");
|
|
10891
10904
|
}
|
|
10892
10905
|
});
|
|
10893
10906
|
|
|
@@ -11088,7 +11101,7 @@ var init_mem7 = __esm({
|
|
|
11088
11101
|
});
|
|
11089
11102
|
|
|
11090
11103
|
// src/memory/proactive/config.ts
|
|
11091
|
-
import { join as
|
|
11104
|
+
import { join as join30 } from "node:path";
|
|
11092
11105
|
function parseProactiveConfig(raw) {
|
|
11093
11106
|
const obj = raw && typeof raw === "object" ? raw : {};
|
|
11094
11107
|
const modelRef = typeof obj.model === "string" ? obj.model.trim() : "";
|
|
@@ -11115,7 +11128,7 @@ function parseProactiveConfig(raw) {
|
|
|
11115
11128
|
};
|
|
11116
11129
|
}
|
|
11117
11130
|
function proactiveDbPath(workspace) {
|
|
11118
|
-
return
|
|
11131
|
+
return join30(workspace, ".proactive", "proactive.db");
|
|
11119
11132
|
}
|
|
11120
11133
|
var init_config3 = __esm({
|
|
11121
11134
|
"src/memory/proactive/config.ts"() {
|
|
@@ -11459,8 +11472,8 @@ var init_graph_store = __esm({
|
|
|
11459
11472
|
|
|
11460
11473
|
// src/memory/proactive/persistence.ts
|
|
11461
11474
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
11462
|
-
import { mkdirSync as
|
|
11463
|
-
import { dirname as
|
|
11475
|
+
import { mkdirSync as mkdirSync12 } from "node:fs";
|
|
11476
|
+
import { dirname as dirname9 } from "node:path";
|
|
11464
11477
|
function rowToAction(r) {
|
|
11465
11478
|
return {
|
|
11466
11479
|
id: r.id,
|
|
@@ -11561,7 +11574,7 @@ CREATE INDEX IF NOT EXISTS idx_proactive_decisions_created ON proactive_decision
|
|
|
11561
11574
|
Persistence = class {
|
|
11562
11575
|
db;
|
|
11563
11576
|
constructor(dbPath) {
|
|
11564
|
-
|
|
11577
|
+
mkdirSync12(dirname9(dbPath), { recursive: true });
|
|
11565
11578
|
this.db = new DatabaseSync3(dbPath);
|
|
11566
11579
|
this.db.exec("PRAGMA journal_mode=WAL");
|
|
11567
11580
|
this.db.exec(SCHEMA2);
|
|
@@ -12308,8 +12321,8 @@ var init_agent_tools = __esm({
|
|
|
12308
12321
|
});
|
|
12309
12322
|
|
|
12310
12323
|
// src/memory/proactive/prompts.ts
|
|
12311
|
-
import { readFileSync as
|
|
12312
|
-
import { join as
|
|
12324
|
+
import { readFileSync as readFileSync22 } from "node:fs";
|
|
12325
|
+
import { join as join31 } from "node:path";
|
|
12313
12326
|
function buildSectionRegistry(D) {
|
|
12314
12327
|
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}.
|
|
12315
12328
|
|
|
@@ -12921,9 +12934,9 @@ Return your response as JSON.`;
|
|
|
12921
12934
|
}
|
|
12922
12935
|
function loadPersona(workspace) {
|
|
12923
12936
|
if (!workspace) return "";
|
|
12924
|
-
const file2 =
|
|
12937
|
+
const file2 = join31(workspace, "prompts", "proactive-persona.md");
|
|
12925
12938
|
try {
|
|
12926
|
-
const text =
|
|
12939
|
+
const text = readFileSync22(file2, "utf8").trim();
|
|
12927
12940
|
if (text) console.log(`[proactive] persona loaded from ${file2} (${text.length} chars)`);
|
|
12928
12941
|
return text;
|
|
12929
12942
|
} catch {
|
|
@@ -12932,9 +12945,9 @@ function loadPersona(workspace) {
|
|
|
12932
12945
|
}
|
|
12933
12946
|
function loadDomain(workspace) {
|
|
12934
12947
|
if (!workspace) return DEFAULT_DOMAIN;
|
|
12935
|
-
const file2 =
|
|
12948
|
+
const file2 = join31(workspace, "prompts", "proactive-domain.json");
|
|
12936
12949
|
try {
|
|
12937
|
-
const raw = JSON.parse(
|
|
12950
|
+
const raw = JSON.parse(readFileSync22(file2, "utf8"));
|
|
12938
12951
|
if (raw && typeof raw === "object") {
|
|
12939
12952
|
const allowed = new Set(Object.keys(DEFAULT_DOMAIN));
|
|
12940
12953
|
const clean = {};
|
|
@@ -13442,7 +13455,7 @@ var init_helpers = __esm({
|
|
|
13442
13455
|
});
|
|
13443
13456
|
|
|
13444
13457
|
// src/calendar/commands.ts
|
|
13445
|
-
import { existsSync as
|
|
13458
|
+
import { existsSync as existsSync18, statSync as statSync4 } from "node:fs";
|
|
13446
13459
|
import { isAbsolute as isAbsolute4, resolve as resolve6 } from "node:path";
|
|
13447
13460
|
function fmtEnd(start, durationMin) {
|
|
13448
13461
|
const [hh, mm] = start.split(":").map(Number);
|
|
@@ -13611,7 +13624,7 @@ function addTask(db2, args2) {
|
|
|
13611
13624
|
}
|
|
13612
13625
|
try {
|
|
13613
13626
|
const absPath = isAbsolute4(docPath) ? docPath : resolve6(process.cwd(), docPath);
|
|
13614
|
-
if (!
|
|
13627
|
+
if (!existsSync18(absPath)) {
|
|
13615
13628
|
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728
|
|
13616
13629
|
\u8DEF\u5F84: ${docPath}
|
|
13617
13630
|
\u89E3\u6790\u540E: ${absPath}
|
|
@@ -14044,8 +14057,8 @@ var init_recall_score = __esm({
|
|
|
14044
14057
|
});
|
|
14045
14058
|
|
|
14046
14059
|
// src/memory/proactive/opportunity.ts
|
|
14047
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
14048
|
-
import { join as
|
|
14060
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync23, existsSync as existsSync19 } from "node:fs";
|
|
14061
|
+
import { join as join32 } from "node:path";
|
|
14049
14062
|
function normalizeOpportunity(raw) {
|
|
14050
14063
|
if (!raw || typeof raw !== "object") return null;
|
|
14051
14064
|
const o = raw;
|
|
@@ -14130,8 +14143,8 @@ function parseForesightEntries(everosRoot, now, userId) {
|
|
|
14130
14143
|
const today3 = todayKey(now);
|
|
14131
14144
|
let files;
|
|
14132
14145
|
if (userId) {
|
|
14133
|
-
const ownDir =
|
|
14134
|
-
files =
|
|
14146
|
+
const ownDir = join32(everosRoot, userId, "default_project", "users", userId, ".foresights");
|
|
14147
|
+
files = existsSync19(ownDir) ? listForesightMds(ownDir) : findForesightFiles(everosRoot);
|
|
14135
14148
|
} else {
|
|
14136
14149
|
files = findForesightFiles(everosRoot);
|
|
14137
14150
|
}
|
|
@@ -14140,7 +14153,7 @@ function parseForesightEntries(everosRoot, now, userId) {
|
|
|
14140
14153
|
for (const file2 of files) {
|
|
14141
14154
|
let content;
|
|
14142
14155
|
try {
|
|
14143
|
-
content =
|
|
14156
|
+
content = readFileSync23(file2, "utf8");
|
|
14144
14157
|
} catch {
|
|
14145
14158
|
continue;
|
|
14146
14159
|
}
|
|
@@ -14180,7 +14193,7 @@ function matchForesightForEvent(entries2, message, maxHits = 2) {
|
|
|
14180
14193
|
}
|
|
14181
14194
|
function listForesightMds(dir) {
|
|
14182
14195
|
try {
|
|
14183
|
-
return readdirSync3(dir).filter((f) => /^foresight-\d{4}-\d{2}-\d{2}\.md$/.test(f)).map((f) =>
|
|
14196
|
+
return readdirSync3(dir).filter((f) => /^foresight-\d{4}-\d{2}-\d{2}\.md$/.test(f)).map((f) => join32(dir, f)).sort();
|
|
14184
14197
|
} catch {
|
|
14185
14198
|
return [];
|
|
14186
14199
|
}
|
|
@@ -14196,7 +14209,7 @@ function findForesightFiles(everosRoot) {
|
|
|
14196
14209
|
return;
|
|
14197
14210
|
}
|
|
14198
14211
|
for (const e of entries2) {
|
|
14199
|
-
const p =
|
|
14212
|
+
const p = join32(dir, e.name);
|
|
14200
14213
|
if (e.isDirectory()) {
|
|
14201
14214
|
if (e.name === ".foresights") {
|
|
14202
14215
|
files.push(...listForesightMds(p));
|
|
@@ -15322,7 +15335,7 @@ var init_intent = __esm({
|
|
|
15322
15335
|
});
|
|
15323
15336
|
|
|
15324
15337
|
// src/memory/proactive/sweep.ts
|
|
15325
|
-
import { readFileSync as
|
|
15338
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
15326
15339
|
function sharesTerm(a, b) {
|
|
15327
15340
|
const x = normalizeTitle(a);
|
|
15328
15341
|
const y = normalizeTitle(b);
|
|
@@ -15542,7 +15555,7 @@ ${JSON.stringify(payload, null, 2)}
|
|
|
15542
15555
|
const file2 = this.deps.promptFile;
|
|
15543
15556
|
if (!file2) return DEFAULT_PROMPT;
|
|
15544
15557
|
try {
|
|
15545
|
-
const text =
|
|
15558
|
+
const text = readFileSync24(file2, "utf8").trim();
|
|
15546
15559
|
return text || DEFAULT_PROMPT;
|
|
15547
15560
|
} catch {
|
|
15548
15561
|
return DEFAULT_PROMPT;
|
|
@@ -15553,14 +15566,14 @@ ${JSON.stringify(payload, null, 2)}
|
|
|
15553
15566
|
});
|
|
15554
15567
|
|
|
15555
15568
|
// src/memory/proactive/proactive-tools.ts
|
|
15556
|
-
import { existsSync as
|
|
15569
|
+
import { existsSync as existsSync20 } from "node:fs";
|
|
15557
15570
|
function setProactiveWorkspace(workspace) {
|
|
15558
15571
|
toolWorkspace = workspace;
|
|
15559
15572
|
}
|
|
15560
15573
|
function withStore(fn) {
|
|
15561
15574
|
if (!toolWorkspace) return null;
|
|
15562
15575
|
const p = proactiveDbPath(toolWorkspace);
|
|
15563
|
-
if (!
|
|
15576
|
+
if (!existsSync20(p)) return null;
|
|
15564
15577
|
const store = new Persistence(p);
|
|
15565
15578
|
try {
|
|
15566
15579
|
return fn(store);
|
|
@@ -15813,8 +15826,8 @@ __export(plugin_exports, {
|
|
|
15813
15826
|
ProactivePlugin: () => ProactivePlugin,
|
|
15814
15827
|
feedMem7Cell: () => feedMem7Cell
|
|
15815
15828
|
});
|
|
15816
|
-
import { join as
|
|
15817
|
-
import { existsSync as
|
|
15829
|
+
import { join as join33 } from "node:path";
|
|
15830
|
+
import { existsSync as existsSync21, readFileSync as readFileSync25, appendFileSync as appendFileSync3 } from "node:fs";
|
|
15818
15831
|
function isFiller(text) {
|
|
15819
15832
|
const t = text.trim();
|
|
15820
15833
|
if (t.length >= 5) return false;
|
|
@@ -15839,7 +15852,7 @@ function buildPlanningContext(calDb, workspace) {
|
|
|
15839
15852
|
}
|
|
15840
15853
|
}
|
|
15841
15854
|
try {
|
|
15842
|
-
const state2 =
|
|
15855
|
+
const state2 = readFileSync25(join33(workspace, "SESSION-STATE.md"), "utf8");
|
|
15843
15856
|
const active = extractActiveState(state2);
|
|
15844
15857
|
if (active) {
|
|
15845
15858
|
lines.push("\n[SESSION-STATE active work]");
|
|
@@ -16036,8 +16049,8 @@ var init_plugin = __esm({
|
|
|
16036
16049
|
});
|
|
16037
16050
|
this.actionAgent = new ActionAgent(this.provider, this.config.modelId, persona);
|
|
16038
16051
|
this.ingestWorkspace = workspace;
|
|
16039
|
-
const calDbPath =
|
|
16040
|
-
this.calDb =
|
|
16052
|
+
const calDbPath = join33(workspace, ".calendar", "calendar.db");
|
|
16053
|
+
this.calDb = existsSync21(calDbPath) ? openDb(workspace) : null;
|
|
16041
16054
|
registerCallbackHook("PostToolUse", {
|
|
16042
16055
|
type: "callback",
|
|
16043
16056
|
id: "proactive-completion-evidence",
|
|
@@ -16076,7 +16089,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
16076
16089
|
const pluginCalDb = this.calDb;
|
|
16077
16090
|
this.sweep = new Sweep({
|
|
16078
16091
|
persist: this.persist,
|
|
16079
|
-
promptFile:
|
|
16092
|
+
promptFile: join33(workspace, "prompts", "proactive.md"),
|
|
16080
16093
|
// 三个都走 getter **每轮现读** —— 热加载规则(config 改了立刻生效)+
|
|
16081
16094
|
// calendar 会变,都不能在 start() 时快照。
|
|
16082
16095
|
get minLeadDays() {
|
|
@@ -16094,7 +16107,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
16094
16107
|
},
|
|
16095
16108
|
// 闸掉的必须留痕:她要能"扫一眼标题,真有冤案我喊"。
|
|
16096
16109
|
onGated: (items) => {
|
|
16097
|
-
const gatedPath =
|
|
16110
|
+
const gatedPath = join33(workspace, ".proactive", "gated.jsonl");
|
|
16098
16111
|
try {
|
|
16099
16112
|
appendFileSync3(
|
|
16100
16113
|
gatedPath,
|
|
@@ -16170,7 +16183,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
16170
16183
|
const nowDate = /* @__PURE__ */ new Date();
|
|
16171
16184
|
const stateDir = String(liveConfig.get("stateDir") ?? "");
|
|
16172
16185
|
if (stateDir) {
|
|
16173
|
-
const all = loadForesightEntries(
|
|
16186
|
+
const all = loadForesightEntries(join33(stateDir, "mem7"), nowDate);
|
|
16174
16187
|
const events = all.filter((e) => e.kind !== "profile");
|
|
16175
16188
|
const mem7Entries = capForesightEntries(events, todayKey(nowDate));
|
|
16176
16189
|
if (all.length > 0) {
|
|
@@ -16312,7 +16325,7 @@ ${String(input.tool_output ?? "")}`
|
|
|
16312
16325
|
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");
|
|
16313
16326
|
if (senderScoped) console.log(`[proactive] sender-scoped recall owners=[${(scopedOwners ?? []).join(",")}]`);
|
|
16314
16327
|
if (stateDir && scopeReady) {
|
|
16315
|
-
const mem7Entries = loadForesightEntries(
|
|
16328
|
+
const mem7Entries = loadForesightEntries(join33(stateDir, "mem7"), now, void 0, scopedOwners);
|
|
16316
16329
|
const bigram = matchForesightForEvent(mem7Entries, prompt);
|
|
16317
16330
|
for (const h of bigram) hitSet.add(`[mem7] ${h.replace(/^- /, "")}`);
|
|
16318
16331
|
if (bigram.length === 0) {
|
|
@@ -16436,17 +16449,17 @@ ${String(input.tool_output ?? "")}`
|
|
|
16436
16449
|
});
|
|
16437
16450
|
|
|
16438
16451
|
// src/memory/sessionMemory/sessionMemoryUtils.ts
|
|
16439
|
-
import { join as
|
|
16440
|
-
import { mkdirSync as
|
|
16452
|
+
import { join as join34 } from "node:path";
|
|
16453
|
+
import { mkdirSync as mkdirSync13, readFileSync as readFileSync26 } from "node:fs";
|
|
16441
16454
|
function setSessionMemoryStateDir(dir) {
|
|
16442
16455
|
_stateDir2 = dir;
|
|
16443
|
-
|
|
16456
|
+
mkdirSync13(dir, { recursive: true });
|
|
16444
16457
|
}
|
|
16445
16458
|
function getSessionMemoryDir() {
|
|
16446
16459
|
return _stateDir2;
|
|
16447
16460
|
}
|
|
16448
16461
|
function getSessionMemoryPath() {
|
|
16449
|
-
return
|
|
16462
|
+
return join34(_stateDir2, "session-notes.md");
|
|
16450
16463
|
}
|
|
16451
16464
|
function markExtractionStarted() {
|
|
16452
16465
|
extractionStartedAt = Date.now();
|
|
@@ -16494,7 +16507,7 @@ var init_sessionMemoryUtils = __esm({
|
|
|
16494
16507
|
|
|
16495
16508
|
// src/memory/sessionMemory/prompts.ts
|
|
16496
16509
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
16497
|
-
import { join as
|
|
16510
|
+
import { join as join35 } from "node:path";
|
|
16498
16511
|
function roughTokenCountEstimation4(text) {
|
|
16499
16512
|
return Math.ceil(text.length / 4);
|
|
16500
16513
|
}
|
|
@@ -16539,7 +16552,7 @@ REMEMBER: Use the Edit tool in parallel and stop. Do not continue after the edit
|
|
|
16539
16552
|
}
|
|
16540
16553
|
async function loadSessionMemoryTemplate() {
|
|
16541
16554
|
const configHome = process.env.CLAUDE_CONFIG_HOME || process.env.HOME || "";
|
|
16542
|
-
const templatePath =
|
|
16555
|
+
const templatePath = join35(configHome, ".claude", "session-memory", "config", "template.md");
|
|
16543
16556
|
try {
|
|
16544
16557
|
return await readFile4(templatePath, { encoding: "utf-8" });
|
|
16545
16558
|
} catch {
|
|
@@ -16548,7 +16561,7 @@ async function loadSessionMemoryTemplate() {
|
|
|
16548
16561
|
}
|
|
16549
16562
|
async function loadSessionMemoryPrompt() {
|
|
16550
16563
|
const configHome = process.env.CLAUDE_CONFIG_HOME || process.env.HOME || "";
|
|
16551
|
-
const promptPath =
|
|
16564
|
+
const promptPath = join35(configHome, ".claude", "session-memory", "config", "prompt.md");
|
|
16552
16565
|
try {
|
|
16553
16566
|
return await readFile4(promptPath, { encoding: "utf-8" });
|
|
16554
16567
|
} catch {
|
|
@@ -16712,7 +16725,7 @@ __export(sessionMemory_exports, {
|
|
|
16712
16725
|
resetLastMemoryMessageUuid: () => resetLastMemoryMessageUuid,
|
|
16713
16726
|
shouldExtractMemory: () => shouldExtractMemory
|
|
16714
16727
|
});
|
|
16715
|
-
import { readFileSync as
|
|
16728
|
+
import { readFileSync as readFileSync27, mkdirSync as mkdirSync14 } from "node:fs";
|
|
16716
16729
|
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
16717
16730
|
function initSessionMemory(deps) {
|
|
16718
16731
|
_deps = deps;
|
|
@@ -16771,11 +16784,11 @@ function shouldExtractMemory(estimatedTokens, messages) {
|
|
|
16771
16784
|
}
|
|
16772
16785
|
async function setupSessionMemoryFile() {
|
|
16773
16786
|
const memoryDir = getSessionMemoryDir();
|
|
16774
|
-
|
|
16787
|
+
mkdirSync14(memoryDir, { recursive: true });
|
|
16775
16788
|
const memoryPath = getSessionMemoryPath();
|
|
16776
16789
|
let currentMemory;
|
|
16777
16790
|
try {
|
|
16778
|
-
currentMemory =
|
|
16791
|
+
currentMemory = readFileSync27(memoryPath, { encoding: "utf-8" });
|
|
16779
16792
|
} catch {
|
|
16780
16793
|
const template = await loadSessionMemoryTemplate();
|
|
16781
16794
|
await writeFile3(memoryPath, template, { encoding: "utf-8" });
|
|
@@ -16852,7 +16865,7 @@ ${messages.filter((m) => m.role === "user" || m.role === "assistant").slice(-20)
|
|
|
16852
16865
|
}
|
|
16853
16866
|
function getSessionMemoryForCompaction() {
|
|
16854
16867
|
try {
|
|
16855
|
-
const content =
|
|
16868
|
+
const content = readFileSync27(getSessionMemoryPath(), { encoding: "utf-8" }).trim();
|
|
16856
16869
|
if (!content) return null;
|
|
16857
16870
|
const { truncatedContent, wasTruncated } = truncateSessionMemoryForCompact(content);
|
|
16858
16871
|
if (wasTruncated) {
|
|
@@ -16885,9 +16898,9 @@ var init_sessionMemory = __esm({
|
|
|
16885
16898
|
|
|
16886
16899
|
// src/memory/autoDream/consolidationLock.ts
|
|
16887
16900
|
import { mkdir as mkdir3, readFile as readFile5, stat as stat3, unlink, utimes, writeFile as writeFile4 } from "node:fs/promises";
|
|
16888
|
-
import { join as
|
|
16901
|
+
import { join as join36 } from "node:path";
|
|
16889
16902
|
function lockPath(memoryDir) {
|
|
16890
|
-
return
|
|
16903
|
+
return join36(memoryDir, LOCK_FILE);
|
|
16891
16904
|
}
|
|
16892
16905
|
async function readLastConsolidatedAt(memoryDir) {
|
|
16893
16906
|
try {
|
|
@@ -16955,7 +16968,7 @@ async function listSessionsTouchedSince(sessionsDir, sinceMs) {
|
|
|
16955
16968
|
const results = [];
|
|
16956
16969
|
for (const f of jsonlFiles) {
|
|
16957
16970
|
try {
|
|
16958
|
-
const s = await stat3(
|
|
16971
|
+
const s = await stat3(join36(sessionsDir, f));
|
|
16959
16972
|
if (s.mtimeMs > sinceMs) {
|
|
16960
16973
|
results.push(f.replace(/\.jsonl$/, ""));
|
|
16961
16974
|
}
|
|
@@ -18491,18 +18504,18 @@ var init_tasks2 = __esm({
|
|
|
18491
18504
|
});
|
|
18492
18505
|
|
|
18493
18506
|
// src/version.ts
|
|
18494
|
-
import { readFileSync as
|
|
18495
|
-
import { dirname as
|
|
18496
|
-
import { fileURLToPath as
|
|
18507
|
+
import { readFileSync as readFileSync33 } from "node:fs";
|
|
18508
|
+
import { dirname as dirname11, join as join44 } from "node:path";
|
|
18509
|
+
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
18497
18510
|
function candidates() {
|
|
18498
|
-
if (_pkgDirOverride !== null) return [
|
|
18499
|
-
const here =
|
|
18500
|
-
return [
|
|
18511
|
+
if (_pkgDirOverride !== null) return [join44(_pkgDirOverride, "package.json")];
|
|
18512
|
+
const here = dirname11(fileURLToPath7(import.meta.url));
|
|
18513
|
+
return [join44(here, "..", "package.json"), join44(here, "..", "..", "package.json")];
|
|
18501
18514
|
}
|
|
18502
18515
|
function readFromDisk() {
|
|
18503
18516
|
for (const p of candidates()) {
|
|
18504
18517
|
try {
|
|
18505
|
-
return JSON.parse(
|
|
18518
|
+
return JSON.parse(readFileSync33(p, "utf-8")).version || "unknown";
|
|
18506
18519
|
} catch {
|
|
18507
18520
|
}
|
|
18508
18521
|
}
|
|
@@ -18651,8 +18664,8 @@ var reply_blocklist_exports = {};
|
|
|
18651
18664
|
__export(reply_blocklist_exports, {
|
|
18652
18665
|
isUserBlocked: () => isUserBlocked
|
|
18653
18666
|
});
|
|
18654
|
-
import { readFileSync as
|
|
18655
|
-
import { join as
|
|
18667
|
+
import { readFileSync as readFileSync34, writeFileSync as writeFileSync12, existsSync as existsSync25 } from "node:fs";
|
|
18668
|
+
import { join as join45 } from "node:path";
|
|
18656
18669
|
function ensureLoaded(workspace, configIds) {
|
|
18657
18670
|
if (loaded) return;
|
|
18658
18671
|
if (configIds?.length) {
|
|
@@ -18660,10 +18673,10 @@ function ensureLoaded(workspace, configIds) {
|
|
|
18660
18673
|
if (!state.blockedUserIds.includes(id)) state.blockedUserIds.push(id);
|
|
18661
18674
|
}
|
|
18662
18675
|
}
|
|
18663
|
-
const path61 =
|
|
18676
|
+
const path61 = join45(workspace, ".reply-blocklist.json");
|
|
18664
18677
|
try {
|
|
18665
|
-
if (
|
|
18666
|
-
const raw =
|
|
18678
|
+
if (existsSync25(path61)) {
|
|
18679
|
+
const raw = readFileSync34(path61, "utf-8");
|
|
18667
18680
|
const parsed = JSON.parse(raw);
|
|
18668
18681
|
if (parsed.blockedUserIds) {
|
|
18669
18682
|
for (const id of parsed.blockedUserIds) {
|
|
@@ -18679,9 +18692,9 @@ function ensureLoaded(workspace, configIds) {
|
|
|
18679
18692
|
loaded = true;
|
|
18680
18693
|
}
|
|
18681
18694
|
function save(workspace) {
|
|
18682
|
-
const path61 =
|
|
18695
|
+
const path61 = join45(workspace, ".reply-blocklist.json");
|
|
18683
18696
|
try {
|
|
18684
|
-
|
|
18697
|
+
writeFileSync12(path61, JSON.stringify(state, null, 2), "utf-8");
|
|
18685
18698
|
} catch (err) {
|
|
18686
18699
|
console.warn(`[reply-blocklist] Failed to save: ${err.message}`);
|
|
18687
18700
|
}
|
|
@@ -24042,6 +24055,7 @@ function startConfigWatcher(config2, deps, provider) {
|
|
|
24042
24055
|
}
|
|
24043
24056
|
});
|
|
24044
24057
|
};
|
|
24058
|
+
consumeSelfWrite();
|
|
24045
24059
|
startWatch();
|
|
24046
24060
|
console.log(`[config-watch] watching ${configPath2}`);
|
|
24047
24061
|
try {
|
|
@@ -24156,17 +24170,81 @@ import * as path16 from "node:path";
|
|
|
24156
24170
|
import fs11 from "node:fs";
|
|
24157
24171
|
import path11 from "node:path";
|
|
24158
24172
|
import { execSync as execSync2 } from "node:child_process";
|
|
24159
|
-
function
|
|
24160
|
-
|
|
24161
|
-
|
|
24173
|
+
function enginePidFile(stateDir) {
|
|
24174
|
+
return path11.join(stateDir, ".engine.pid");
|
|
24175
|
+
}
|
|
24176
|
+
function isEngineImage(text) {
|
|
24177
|
+
return /node|engine7|electron/i.test(text);
|
|
24178
|
+
}
|
|
24179
|
+
function isPidAlive(pid) {
|
|
24180
|
+
try {
|
|
24181
|
+
process.kill(pid, 0);
|
|
24182
|
+
return true;
|
|
24183
|
+
} catch {
|
|
24184
|
+
return false;
|
|
24185
|
+
}
|
|
24186
|
+
}
|
|
24187
|
+
function probeImage(pid) {
|
|
24162
24188
|
try {
|
|
24163
|
-
|
|
24164
|
-
|
|
24165
|
-
|
|
24166
|
-
|
|
24189
|
+
if (process.platform === "win32") {
|
|
24190
|
+
return execSync2(`tasklist /FI "PID eq ${pid}" /NH /FO CSV`, {
|
|
24191
|
+
encoding: "utf-8",
|
|
24192
|
+
timeout: 3e3,
|
|
24193
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
24194
|
+
});
|
|
24195
|
+
}
|
|
24196
|
+
if (process.platform === "darwin") {
|
|
24197
|
+
return execSync2(`ps -p ${pid} -o comm=`, {
|
|
24198
|
+
encoding: "utf-8",
|
|
24199
|
+
timeout: 3e3,
|
|
24200
|
+
stdio: ["ignore", "pipe", "ignore"]
|
|
24201
|
+
});
|
|
24167
24202
|
}
|
|
24203
|
+
return fs11.readFileSync(`/proc/${pid}/comm`, "utf-8");
|
|
24204
|
+
} catch {
|
|
24205
|
+
return null;
|
|
24206
|
+
}
|
|
24207
|
+
}
|
|
24208
|
+
function probeEngineImage(pid) {
|
|
24209
|
+
return isEngineImage(probeImage(pid) ?? "");
|
|
24210
|
+
}
|
|
24211
|
+
function isCliWrapperImage(text) {
|
|
24212
|
+
return /node/i.test(text);
|
|
24213
|
+
}
|
|
24214
|
+
function probeIsCliWrapper(pid) {
|
|
24215
|
+
return isCliWrapperImage(probeImage(pid) ?? "");
|
|
24216
|
+
}
|
|
24217
|
+
function readOwnEnginePidText(stateDir) {
|
|
24218
|
+
try {
|
|
24219
|
+
return fs11.readFileSync(enginePidFile(stateDir), "utf-8");
|
|
24168
24220
|
} catch (err) {
|
|
24169
24221
|
if (err?.code !== "ENOENT") console.warn(`[pid-lock] read lock failed: ${err.message}`);
|
|
24222
|
+
return null;
|
|
24223
|
+
}
|
|
24224
|
+
}
|
|
24225
|
+
function pickOwnEnginePid(probe) {
|
|
24226
|
+
const pid = parseInt((probe.pidFileContent ?? "").trim(), 10);
|
|
24227
|
+
if (!Number.isInteger(pid) || pid <= 0) return null;
|
|
24228
|
+
if (pid === probe.myPid) return null;
|
|
24229
|
+
if (!probe.isAlive(pid)) return null;
|
|
24230
|
+
if (!probe.isEngineImage(pid)) return null;
|
|
24231
|
+
return pid;
|
|
24232
|
+
}
|
|
24233
|
+
function ownEnginePid(stateDir, myPid = process.pid) {
|
|
24234
|
+
return pickOwnEnginePid({
|
|
24235
|
+
pidFileContent: readOwnEnginePidText(stateDir),
|
|
24236
|
+
myPid,
|
|
24237
|
+
isAlive: isPidAlive,
|
|
24238
|
+
isEngineImage: probeEngineImage
|
|
24239
|
+
});
|
|
24240
|
+
}
|
|
24241
|
+
function acquireEngineLock(stateDir) {
|
|
24242
|
+
const lockFile = enginePidFile(stateDir);
|
|
24243
|
+
const myPid = process.pid;
|
|
24244
|
+
const stale = ownEnginePid(stateDir, myPid);
|
|
24245
|
+
if (stale !== null) {
|
|
24246
|
+
console.log(`[pid-lock] Stale engine PID ${stale} still alive (engine), killing tree...`);
|
|
24247
|
+
killTree(stale);
|
|
24170
24248
|
}
|
|
24171
24249
|
try {
|
|
24172
24250
|
fs11.mkdirSync(stateDir, { recursive: true });
|
|
@@ -24192,54 +24270,42 @@ function acquireEngineLock(stateDir) {
|
|
|
24192
24270
|
process.exit(0);
|
|
24193
24271
|
});
|
|
24194
24272
|
}
|
|
24195
|
-
function
|
|
24196
|
-
|
|
24197
|
-
|
|
24198
|
-
|
|
24199
|
-
|
|
24200
|
-
}
|
|
24201
|
-
try {
|
|
24202
|
-
if (process.platform === "win32") {
|
|
24203
|
-
const out = execSync2(`tasklist /FI "PID eq ${pid}" /NH /FO CSV`, {
|
|
24204
|
-
encoding: "utf-8",
|
|
24205
|
-
timeout: 3e3,
|
|
24206
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
24207
|
-
});
|
|
24208
|
-
return /node\.exe/i.test(out);
|
|
24209
|
-
} else if (process.platform === "darwin") {
|
|
24210
|
-
const out = execSync2(`ps -p ${pid} -o comm=`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] });
|
|
24211
|
-
return /node/.test(out);
|
|
24212
|
-
}
|
|
24213
|
-
return /node/.test(fs11.readFileSync(`/proc/${pid}/cmdline`, "utf-8"));
|
|
24214
|
-
} catch {
|
|
24215
|
-
return false;
|
|
24216
|
-
}
|
|
24273
|
+
function pickParentPid(procStatus, psOutput) {
|
|
24274
|
+
const fromProc = Number(/PPid:\s*(\d+)/.exec(procStatus ?? "")?.[1] ?? NaN);
|
|
24275
|
+
if (Number.isInteger(fromProc) && fromProc > 0) return fromProc;
|
|
24276
|
+
const fromPs = Number((psOutput ?? "").trim());
|
|
24277
|
+
return Number.isInteger(fromPs) && fromPs > 0 ? fromPs : 0;
|
|
24217
24278
|
}
|
|
24218
24279
|
function killTree(pid) {
|
|
24219
24280
|
try {
|
|
24220
24281
|
if (process.platform === "win32") {
|
|
24221
24282
|
execSync2(`taskkill /PID ${pid} /T /F`, { stdio: "ignore", timeout: 8e3 });
|
|
24222
24283
|
try {
|
|
24223
|
-
const parentPid = execSync2(`wmic process where ProcessId=${pid} get ParentProcessId /value`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).match(/ParentProcessId=(\d+)/)?.[1];
|
|
24224
|
-
if (parentPid &&
|
|
24284
|
+
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);
|
|
24285
|
+
if (parentPid && parentPid !== process.ppid && probeIsCliWrapper(parentPid)) {
|
|
24225
24286
|
execSync2(`taskkill /PID ${parentPid} /F`, { stdio: "ignore", timeout: 3e3 });
|
|
24226
24287
|
}
|
|
24227
24288
|
} catch {
|
|
24228
24289
|
}
|
|
24229
24290
|
} else {
|
|
24230
24291
|
process.kill(pid, "SIGKILL");
|
|
24292
|
+
let parentPid = 0;
|
|
24231
24293
|
try {
|
|
24232
|
-
|
|
24233
|
-
const macPpid = parseInt(execSync2(`ps -p ${pid} -o ppid=`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }).trim(), 10);
|
|
24234
|
-
const parentPid = ppid || macPpid;
|
|
24235
|
-
if (parentPid && parentPid > 1) {
|
|
24236
|
-
try {
|
|
24237
|
-
process.kill(parentPid, "SIGKILL");
|
|
24238
|
-
} catch {
|
|
24239
|
-
}
|
|
24240
|
-
}
|
|
24294
|
+
parentPid = pickParentPid(fs11.readFileSync(`/proc/${pid}/status`, "utf-8"), null);
|
|
24241
24295
|
} catch {
|
|
24242
24296
|
}
|
|
24297
|
+
if (!parentPid) {
|
|
24298
|
+
try {
|
|
24299
|
+
parentPid = pickParentPid(null, execSync2(`ps -p ${pid} -o ppid=`, { encoding: "utf-8", timeout: 3e3, stdio: ["ignore", "pipe", "ignore"] }));
|
|
24300
|
+
} catch {
|
|
24301
|
+
}
|
|
24302
|
+
}
|
|
24303
|
+
if (parentPid > 1 && parentPid !== process.ppid && probeIsCliWrapper(parentPid)) {
|
|
24304
|
+
try {
|
|
24305
|
+
process.kill(parentPid, "SIGKILL");
|
|
24306
|
+
} catch {
|
|
24307
|
+
}
|
|
24308
|
+
}
|
|
24243
24309
|
}
|
|
24244
24310
|
} catch (err) {
|
|
24245
24311
|
console.warn(`[pid-lock] kill ${pid} failed: ${err.message}`);
|
|
@@ -25757,6 +25823,18 @@ var FIELDS = [
|
|
|
25757
25823
|
|
|
25758
25824
|
// src/cli-init-config.ts
|
|
25759
25825
|
var FREE_TIER_RELAY_URL = "https://www.twinsun.top:8866";
|
|
25826
|
+
var FREE_TIER_PROVIDER_ID = "7yi";
|
|
25827
|
+
var DEFAULT_FREE_VOICE = "Chinese (Mandarin)_Warm_Girl";
|
|
25828
|
+
function freeTierVoiceConfig(existing) {
|
|
25829
|
+
const mv = existing && typeof existing === "object" ? existing : {};
|
|
25830
|
+
return {
|
|
25831
|
+
...mv,
|
|
25832
|
+
provider: "relay",
|
|
25833
|
+
relayProviderId: FREE_TIER_PROVIDER_ID,
|
|
25834
|
+
relayModel: "engine7-tts",
|
|
25835
|
+
voice: mv.voice || DEFAULT_FREE_VOICE
|
|
25836
|
+
};
|
|
25837
|
+
}
|
|
25760
25838
|
var VISION_CAPABLE = {
|
|
25761
25839
|
// 0917:原先标 true,但同一个文件里 qwen3.8-max 的 input 是 ['text'],安装器目录
|
|
25762
25840
|
// 也明确标 vision=false(只有 Flash 叫"多模态")。矛盾直接导致**默认 CLI 装机路径**
|
|
@@ -25991,6 +26069,104 @@ function applyFreeTierVideoFixup(io) {
|
|
|
25991
26069
|
return changed;
|
|
25992
26070
|
}
|
|
25993
26071
|
|
|
26072
|
+
// src/provision-free.ts
|
|
26073
|
+
import { randomBytes as randomBytes2, randomUUID as randomUUID5 } from "node:crypto";
|
|
26074
|
+
import { chmodSync as chmodSync2, existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync4 } from "node:fs";
|
|
26075
|
+
import { dirname as dirname3, join as join14 } from "node:path";
|
|
26076
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
26077
|
+
var __filename = fileURLToPath2(import.meta.url);
|
|
26078
|
+
var IDENTITY_FILE = "install-identity.json";
|
|
26079
|
+
function readContactEmailOf(parsed) {
|
|
26080
|
+
return typeof parsed?.contactEmail === "string" ? parsed.contactEmail.trim() : "";
|
|
26081
|
+
}
|
|
26082
|
+
function loadOrCreateInstallIdentity(stateDir) {
|
|
26083
|
+
const file2 = join14(stateDir, IDENTITY_FILE);
|
|
26084
|
+
if (existsSync10(file2)) {
|
|
26085
|
+
let parsed;
|
|
26086
|
+
try {
|
|
26087
|
+
parsed = JSON.parse(readFileSync9(file2, "utf8"));
|
|
26088
|
+
} catch (e) {
|
|
26089
|
+
throw new Error(
|
|
26090
|
+
`${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`
|
|
26091
|
+
);
|
|
26092
|
+
}
|
|
26093
|
+
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
26094
|
+
throw new Error(`${IDENTITY_FILE} \u7F3A installId / installSecret \u5B57\u6BB5`);
|
|
26095
|
+
}
|
|
26096
|
+
const email = readContactEmailOf(parsed);
|
|
26097
|
+
return {
|
|
26098
|
+
installId: parsed.installId,
|
|
26099
|
+
installSecret: parsed.installSecret,
|
|
26100
|
+
...email ? { contactEmail: email } : {}
|
|
26101
|
+
};
|
|
26102
|
+
}
|
|
26103
|
+
const identity = {
|
|
26104
|
+
// 服务端校验 installId 长度为 8..36、只允许字母数字和连字符;uuid 正好符合
|
|
26105
|
+
installId: randomUUID5(),
|
|
26106
|
+
// 服务端校验 installSecret 为 32..64 位十六进制
|
|
26107
|
+
installSecret: randomBytes2(32).toString("hex")
|
|
26108
|
+
};
|
|
26109
|
+
mkdirSync7(stateDir, { recursive: true });
|
|
26110
|
+
writeFileSync4(file2, JSON.stringify(identity, null, 2) + "\n", { mode: 384 });
|
|
26111
|
+
try {
|
|
26112
|
+
chmodSync2(file2, 384);
|
|
26113
|
+
} catch {
|
|
26114
|
+
}
|
|
26115
|
+
return identity;
|
|
26116
|
+
}
|
|
26117
|
+
function readInstallIdentityDetailed(stateDir) {
|
|
26118
|
+
const file2 = join14(stateDir, IDENTITY_FILE);
|
|
26119
|
+
if (!existsSync10(file2)) return { ok: false, reason: "missing" };
|
|
26120
|
+
let text;
|
|
26121
|
+
try {
|
|
26122
|
+
text = readFileSync9(file2, "utf8");
|
|
26123
|
+
} catch (e) {
|
|
26124
|
+
return { ok: false, reason: "corrupt", detail: `\u5B58\u5728\u4F46\u8BFB\u4E0D\u4E86\uFF08${e?.message ?? e}\uFF09` };
|
|
26125
|
+
}
|
|
26126
|
+
let parsed;
|
|
26127
|
+
try {
|
|
26128
|
+
parsed = JSON.parse(text);
|
|
26129
|
+
} catch (e) {
|
|
26130
|
+
return { ok: false, reason: "corrupt", detail: `\u4E0D\u662F\u5408\u6CD5 JSON\uFF08${e?.message ?? e}\uFF09` };
|
|
26131
|
+
}
|
|
26132
|
+
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
26133
|
+
return { ok: false, reason: "corrupt", detail: "\u7F3A installId / installSecret \u5B57\u6BB5" };
|
|
26134
|
+
}
|
|
26135
|
+
const email = readContactEmailOf(parsed);
|
|
26136
|
+
return {
|
|
26137
|
+
ok: true,
|
|
26138
|
+
identity: {
|
|
26139
|
+
installId: parsed.installId,
|
|
26140
|
+
installSecret: parsed.installSecret,
|
|
26141
|
+
...email ? { contactEmail: email } : {}
|
|
26142
|
+
}
|
|
26143
|
+
};
|
|
26144
|
+
}
|
|
26145
|
+
|
|
26146
|
+
// src/free-tier-apply.ts
|
|
26147
|
+
function isFreeTierConfig(cfg) {
|
|
26148
|
+
const hasProvider = !!cfg?.models?.providers?.[FREE_TIER_PROVIDER_ID];
|
|
26149
|
+
const primary = String(cfg?.agents?.defaults?.model?.primary || "");
|
|
26150
|
+
return hasProvider && primary.startsWith(`${FREE_TIER_PROVIDER_ID}/`);
|
|
26151
|
+
}
|
|
26152
|
+
|
|
26153
|
+
// src/startup/free-tier-voice-fixup.ts
|
|
26154
|
+
function needsFreeTierVoiceFixup(cfg) {
|
|
26155
|
+
if (!isFreeTierConfig(cfg)) return false;
|
|
26156
|
+
return cfg?.tools?.my_voice === void 0;
|
|
26157
|
+
}
|
|
26158
|
+
async function applyFreeTierVoiceFixup(io) {
|
|
26159
|
+
const cfg = io.all();
|
|
26160
|
+
if (!needsFreeTierVoiceFixup(cfg)) return false;
|
|
26161
|
+
const persisted = await io.set("tools.my_voice", freeTierVoiceConfig());
|
|
26162
|
+
if (persisted === false) {
|
|
26163
|
+
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");
|
|
26164
|
+
return true;
|
|
26165
|
+
}
|
|
26166
|
+
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");
|
|
26167
|
+
return true;
|
|
26168
|
+
}
|
|
26169
|
+
|
|
25994
26170
|
// src/startup/hooks-boot.ts
|
|
25995
26171
|
init_live();
|
|
25996
26172
|
import * as fs23 from "node:fs";
|
|
@@ -27044,7 +27220,7 @@ ${manifest}`
|
|
|
27044
27220
|
// src/memory/memdir/findRelevantMemoriesVector.ts
|
|
27045
27221
|
init_well_formed();
|
|
27046
27222
|
import { statSync as statSync3 } from "node:fs";
|
|
27047
|
-
import { join as
|
|
27223
|
+
import { join as join20, resolve as resolve5, sep as sep4 } from "node:path";
|
|
27048
27224
|
import { createRequire as createRequire2 } from "node:module";
|
|
27049
27225
|
var require2 = createRequire2(import.meta.url);
|
|
27050
27226
|
var DEFAULT_TOP_K = 3;
|
|
@@ -27197,7 +27373,7 @@ async function findRelevantMemoriesVector(query, memoryDir, alreadySurfaced = /*
|
|
|
27197
27373
|
}
|
|
27198
27374
|
const scored = [];
|
|
27199
27375
|
for (const row of rows) {
|
|
27200
|
-
const absPath =
|
|
27376
|
+
const absPath = join20(memoryDir, row.file_path.replace(/\//g, sep4));
|
|
27201
27377
|
if (alreadySurfaced.has(absPath) || alreadySurfaced.has(row.file_path)) continue;
|
|
27202
27378
|
const emb = new Float32Array(row.embedding.buffer, row.embedding.byteOffset, row.embedding.byteLength / 4);
|
|
27203
27379
|
const score = cosineSim(qVec, emb);
|
|
@@ -27410,27 +27586,27 @@ ${ep.episode || ep.summary}`,
|
|
|
27410
27586
|
|
|
27411
27587
|
// src/handle-query.ts
|
|
27412
27588
|
init_paths();
|
|
27413
|
-
import { readFileSync as
|
|
27414
|
-
import { join as
|
|
27589
|
+
import { readFileSync as readFileSync28, existsSync as existsSync22, statSync as statSync5 } from "node:fs";
|
|
27590
|
+
import { join as join37, resolve as resolve7 } from "node:path";
|
|
27415
27591
|
import * as path21 from "node:path";
|
|
27416
27592
|
|
|
27417
27593
|
// src/light-mode.ts
|
|
27418
27594
|
init_live();
|
|
27419
|
-
import { readFileSync as
|
|
27595
|
+
import { readFileSync as readFileSync14 } from "node:fs";
|
|
27420
27596
|
|
|
27421
27597
|
// src/config/persona-files.ts
|
|
27422
|
-
import { existsSync as
|
|
27423
|
-
import { join as
|
|
27598
|
+
import { existsSync as existsSync13 } from "node:fs";
|
|
27599
|
+
import { join as join21 } from "node:path";
|
|
27424
27600
|
var LEGACY_RELATIVE = {
|
|
27425
27601
|
"my-inner-voice.md": "prompts/my-inner-voice.md"
|
|
27426
27602
|
};
|
|
27427
27603
|
function resolvePersonaFile(workspace, persona, name) {
|
|
27428
27604
|
if (persona) {
|
|
27429
|
-
const scoped =
|
|
27430
|
-
if (
|
|
27605
|
+
const scoped = join21(workspace, "personas", persona, name);
|
|
27606
|
+
if (existsSync13(scoped)) return scoped;
|
|
27431
27607
|
}
|
|
27432
|
-
const legacy =
|
|
27433
|
-
return
|
|
27608
|
+
const legacy = join21(workspace, LEGACY_RELATIVE[name] ?? name);
|
|
27609
|
+
return existsSync13(legacy) ? legacy : null;
|
|
27434
27610
|
}
|
|
27435
27611
|
|
|
27436
27612
|
// src/light-mode.ts
|
|
@@ -27471,7 +27647,7 @@ function buildLightStablePrompt(workspace, mode, opts) {
|
|
|
27471
27647
|
const filePath = resolvePersonaFile(workspace, persona, f);
|
|
27472
27648
|
if (!filePath) continue;
|
|
27473
27649
|
try {
|
|
27474
|
-
parts.push(
|
|
27650
|
+
parts.push(readFileSync14(filePath, "utf-8").trim());
|
|
27475
27651
|
} catch {
|
|
27476
27652
|
}
|
|
27477
27653
|
}
|
|
@@ -27555,8 +27731,8 @@ function voiceFastView(history, opts = VOICE_FAST_DEFAULTS) {
|
|
|
27555
27731
|
|
|
27556
27732
|
// src/sender-context.ts
|
|
27557
27733
|
init_clock();
|
|
27558
|
-
import { readFileSync as
|
|
27559
|
-
import { join as
|
|
27734
|
+
import { readFileSync as readFileSync15, existsSync as existsSync15 } from "node:fs";
|
|
27735
|
+
import { join as join22 } from "node:path";
|
|
27560
27736
|
var contactMap = null;
|
|
27561
27737
|
var externalChanWhitelist = null;
|
|
27562
27738
|
function loadContactMap(workspace) {
|
|
@@ -27564,10 +27740,10 @@ function loadContactMap(workspace) {
|
|
|
27564
27740
|
contactMap = /* @__PURE__ */ new Map();
|
|
27565
27741
|
externalChanWhitelist = /* @__PURE__ */ new Set();
|
|
27566
27742
|
try {
|
|
27567
|
-
const contactsPath =
|
|
27568
|
-
console.log(`[meta] Loading contacts from ${contactsPath}, exists=${
|
|
27569
|
-
if (
|
|
27570
|
-
const text =
|
|
27743
|
+
const contactsPath = join22(workspace, "prompts", "contacts.md");
|
|
27744
|
+
console.log(`[meta] Loading contacts from ${contactsPath}, exists=${existsSync15(contactsPath)}`);
|
|
27745
|
+
if (existsSync15(contactsPath)) {
|
|
27746
|
+
const text = readFileSync15(contactsPath, "utf-8");
|
|
27571
27747
|
const lines = text.split("\n");
|
|
27572
27748
|
for (const line of lines) {
|
|
27573
27749
|
const m = line.match(/^\|\s*(.+?)\s*\|\s*([a-zA-Z0-9_@.]+)\s*\|/);
|
|
@@ -27656,12 +27832,12 @@ function resetSessionStartInjection(sessionId) {
|
|
|
27656
27832
|
}
|
|
27657
27833
|
var externalChanRulesCache = null;
|
|
27658
27834
|
function loadExternalChanRules(workspace) {
|
|
27659
|
-
const path61 =
|
|
27835
|
+
const path61 = join37(workspace, "prompts", "external-chan-rules.md");
|
|
27660
27836
|
if (externalChanRulesCache && externalChanRulesCache.path === path61) return externalChanRulesCache;
|
|
27661
27837
|
let content = "";
|
|
27662
|
-
if (
|
|
27838
|
+
if (existsSync22(path61)) {
|
|
27663
27839
|
try {
|
|
27664
|
-
content =
|
|
27840
|
+
content = readFileSync28(path61, "utf-8").trim();
|
|
27665
27841
|
} catch (e) {
|
|
27666
27842
|
console.warn(`[external-chan-rules] Failed to load: ${e}`);
|
|
27667
27843
|
}
|
|
@@ -27832,7 +28008,7 @@ ${text}` : text });
|
|
|
27832
28008
|
}
|
|
27833
28009
|
if (source === "user") {
|
|
27834
28010
|
try {
|
|
27835
|
-
const wm =
|
|
28011
|
+
const wm = readFileSync28(join37(workspace, ".work-mode"), "utf-8").trim();
|
|
27836
28012
|
if (wm === "on" && chatMode !== "work") {
|
|
27837
28013
|
chatMode = "work";
|
|
27838
28014
|
console.log(`[mode] ${sessionId} /work on \u2192 \u5F3A\u5236 work`);
|
|
@@ -28075,7 +28251,7 @@ ${text}` : text });
|
|
|
28075
28251
|
for (const memPath of newPaths) {
|
|
28076
28252
|
try {
|
|
28077
28253
|
const stat4 = statSync5(memPath);
|
|
28078
|
-
const content =
|
|
28254
|
+
const content = readFileSync28(memPath, "utf-8");
|
|
28079
28255
|
const header = memoryHeader(memPath, stat4.mtimeMs);
|
|
28080
28256
|
restoredMemories.push({ path: memPath, content, mtimeMs: stat4.mtimeMs, header });
|
|
28081
28257
|
} catch {
|
|
@@ -28162,7 +28338,7 @@ ${text}` : text });
|
|
|
28162
28338
|
const attachmentMemories = [];
|
|
28163
28339
|
for (const mem of relevantMemories) {
|
|
28164
28340
|
try {
|
|
28165
|
-
const content = mem.content ??
|
|
28341
|
+
const content = mem.content ?? readFileSync28(mem.path, "utf-8");
|
|
28166
28342
|
const header = mem.header ?? memoryHeader(mem.path, mem.mtimeMs);
|
|
28167
28343
|
attachmentMemories.push({ path: mem.path, content, mtimeMs: mem.mtimeMs, header });
|
|
28168
28344
|
} catch {
|
|
@@ -28482,7 +28658,7 @@ stack: ${err.stack ?? "(none)"}`);
|
|
|
28482
28658
|
}
|
|
28483
28659
|
} catch (err) {
|
|
28484
28660
|
try {
|
|
28485
|
-
(await import("node:fs")).appendFileSync(
|
|
28661
|
+
(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}
|
|
28486
28662
|
stack: ${err.stack ?? "(none)"}
|
|
28487
28663
|
`);
|
|
28488
28664
|
} catch {
|
|
@@ -35088,80 +35264,6 @@ ${inbound.content}` }, ...videoBlocks];
|
|
|
35088
35264
|
// src/optional/reporting/reporter.ts
|
|
35089
35265
|
init_live();
|
|
35090
35266
|
|
|
35091
|
-
// src/provision-free.ts
|
|
35092
|
-
import { randomBytes as randomBytes4, randomUUID as randomUUID6 } from "node:crypto";
|
|
35093
|
-
import { chmodSync as chmodSync2, existsSync as existsSync25, mkdirSync as mkdirSync16, readFileSync as readFileSync35, writeFileSync as writeFileSync13 } from "node:fs";
|
|
35094
|
-
import { dirname as dirname12, join as join47 } from "node:path";
|
|
35095
|
-
import { fileURLToPath as fileURLToPath7 } from "node:url";
|
|
35096
|
-
var __filename = fileURLToPath7(import.meta.url);
|
|
35097
|
-
var IDENTITY_FILE = "install-identity.json";
|
|
35098
|
-
function readContactEmailOf(parsed) {
|
|
35099
|
-
return typeof parsed?.contactEmail === "string" ? parsed.contactEmail.trim() : "";
|
|
35100
|
-
}
|
|
35101
|
-
function loadOrCreateInstallIdentity(stateDir) {
|
|
35102
|
-
const file2 = join47(stateDir, IDENTITY_FILE);
|
|
35103
|
-
if (existsSync25(file2)) {
|
|
35104
|
-
let parsed;
|
|
35105
|
-
try {
|
|
35106
|
-
parsed = JSON.parse(readFileSync35(file2, "utf8"));
|
|
35107
|
-
} catch (e) {
|
|
35108
|
-
throw new Error(
|
|
35109
|
-
`${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`
|
|
35110
|
-
);
|
|
35111
|
-
}
|
|
35112
|
-
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
35113
|
-
throw new Error(`${IDENTITY_FILE} \u7F3A installId / installSecret \u5B57\u6BB5`);
|
|
35114
|
-
}
|
|
35115
|
-
const email = readContactEmailOf(parsed);
|
|
35116
|
-
return {
|
|
35117
|
-
installId: parsed.installId,
|
|
35118
|
-
installSecret: parsed.installSecret,
|
|
35119
|
-
...email ? { contactEmail: email } : {}
|
|
35120
|
-
};
|
|
35121
|
-
}
|
|
35122
|
-
const identity = {
|
|
35123
|
-
// 服务端校验 installId 长度为 8..36、只允许字母数字和连字符;uuid 正好符合
|
|
35124
|
-
installId: randomUUID6(),
|
|
35125
|
-
// 服务端校验 installSecret 为 32..64 位十六进制
|
|
35126
|
-
installSecret: randomBytes4(32).toString("hex")
|
|
35127
|
-
};
|
|
35128
|
-
mkdirSync16(stateDir, { recursive: true });
|
|
35129
|
-
writeFileSync13(file2, JSON.stringify(identity, null, 2) + "\n", { mode: 384 });
|
|
35130
|
-
try {
|
|
35131
|
-
chmodSync2(file2, 384);
|
|
35132
|
-
} catch {
|
|
35133
|
-
}
|
|
35134
|
-
return identity;
|
|
35135
|
-
}
|
|
35136
|
-
function readInstallIdentityDetailed(stateDir) {
|
|
35137
|
-
const file2 = join47(stateDir, IDENTITY_FILE);
|
|
35138
|
-
if (!existsSync25(file2)) return { ok: false, reason: "missing" };
|
|
35139
|
-
let text;
|
|
35140
|
-
try {
|
|
35141
|
-
text = readFileSync35(file2, "utf8");
|
|
35142
|
-
} catch (e) {
|
|
35143
|
-
return { ok: false, reason: "corrupt", detail: `\u5B58\u5728\u4F46\u8BFB\u4E0D\u4E86\uFF08${e?.message ?? e}\uFF09` };
|
|
35144
|
-
}
|
|
35145
|
-
let parsed;
|
|
35146
|
-
try {
|
|
35147
|
-
parsed = JSON.parse(text);
|
|
35148
|
-
} catch (e) {
|
|
35149
|
-
return { ok: false, reason: "corrupt", detail: `\u4E0D\u662F\u5408\u6CD5 JSON\uFF08${e?.message ?? e}\uFF09` };
|
|
35150
|
-
}
|
|
35151
|
-
if (typeof parsed?.installId !== "string" || typeof parsed?.installSecret !== "string") {
|
|
35152
|
-
return { ok: false, reason: "corrupt", detail: "\u7F3A installId / installSecret \u5B57\u6BB5" };
|
|
35153
|
-
}
|
|
35154
|
-
const email = readContactEmailOf(parsed);
|
|
35155
|
-
return {
|
|
35156
|
-
ok: true,
|
|
35157
|
-
identity: {
|
|
35158
|
-
installId: parsed.installId,
|
|
35159
|
-
installSecret: parsed.installSecret,
|
|
35160
|
-
...email ? { contactEmail: email } : {}
|
|
35161
|
-
}
|
|
35162
|
-
};
|
|
35163
|
-
}
|
|
35164
|
-
|
|
35165
35267
|
// src/optional/reporting/state.ts
|
|
35166
35268
|
import { existsSync as existsSync26, mkdirSync as mkdirSync17, readFileSync as readFileSync36, writeFileSync as writeFileSync14 } from "node:fs";
|
|
35167
35269
|
import { join as join48 } from "node:path";
|
|
@@ -36029,6 +36131,21 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
36029
36131
|
}
|
|
36030
36132
|
}
|
|
36031
36133
|
}
|
|
36134
|
+
/**
|
|
36135
|
+
* 检查飞书 API 的**业务返回码**(1001)。
|
|
36136
|
+
*
|
|
36137
|
+
* SDK 只在 **HTTP 非 2xx** 时抛错;业务错误走的是 "HTTP 200 + code≠0" —— 不查码就等于把
|
|
36138
|
+
* "飞书拒了"读成"发出去了"。客户那台 mac 的语音条"日志 Voice sent!、人没收到"卡了一整天
|
|
36139
|
+
* 就是卡在这儿:**引擎从不看码,所以线上到底是发成功了还是被拒了,日志里一个字都没有**。
|
|
36140
|
+
* (1001 实测:同一套参数在我方租户 code:0 全绿,把时长/内容形状/chat_id 通道三项嫌疑逐条排除,
|
|
36141
|
+
* 嫌疑因此全部落到"客户租户返回了什么"上——而那个答案以前根本打印不出来。)
|
|
36142
|
+
*/
|
|
36143
|
+
_assertApiOk(res, what) {
|
|
36144
|
+
const code = res?.code;
|
|
36145
|
+
if (typeof code === "number" && code !== 0) {
|
|
36146
|
+
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`);
|
|
36147
|
+
}
|
|
36148
|
+
}
|
|
36032
36149
|
/** 发送媒体附件(图片/文件) */
|
|
36033
36150
|
async sendFile(target, message, attachment) {
|
|
36034
36151
|
const fs60 = await import("node:fs");
|
|
@@ -36046,25 +36163,25 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
36046
36163
|
const imageKey = await this._uploadImage(fileBuffer, filename);
|
|
36047
36164
|
if (message) {
|
|
36048
36165
|
const postContent = this._buildImagePost(message, imageKey);
|
|
36049
|
-
await this.client.im.message.create({
|
|
36166
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
36050
36167
|
params: { receive_id_type: receiveIdType },
|
|
36051
36168
|
data: { receive_id: safeTarget, msg_type: "post", content: JSON.stringify(postContent) }
|
|
36052
|
-
});
|
|
36169
|
+
}), "\u56FE\u7247\u6D88\u606F\u53D1\u9001");
|
|
36053
36170
|
} else {
|
|
36054
|
-
await this.client.im.message.create({
|
|
36171
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
36055
36172
|
params: { receive_id_type: receiveIdType },
|
|
36056
36173
|
data: { receive_id: safeTarget, msg_type: "image", content: JSON.stringify({ image_key: imageKey }) }
|
|
36057
|
-
});
|
|
36174
|
+
}), "\u56FE\u7247\u6D88\u606F\u53D1\u9001");
|
|
36058
36175
|
}
|
|
36059
36176
|
} else if (mimeType.startsWith("audio/")) {
|
|
36060
36177
|
const isOpus = filename.endsWith(".opus") || filename.endsWith(".ogg") || mimeType === "audio/opus";
|
|
36061
36178
|
if (!isOpus) {
|
|
36062
36179
|
console.warn(`[feishu:sendFile] audio '${filename}' \u4E0D\u662Fopus\uFF0C\u964D\u7EA7\u4E3A\u6587\u4EF6\u6D88\u606F\uFF08\u975E\u8BED\u97F3\u6761\uFF09`);
|
|
36063
36180
|
const fileKey = await this._uploadFile(fileBuffer, filename);
|
|
36064
|
-
await this.client.im.message.create({
|
|
36181
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
36065
36182
|
params: { receive_id_type: receiveIdType },
|
|
36066
36183
|
data: { receive_id: safeTarget, msg_type: "file", content: JSON.stringify({ file_key: fileKey }) }
|
|
36067
|
-
});
|
|
36184
|
+
}), "\u6587\u4EF6\u6D88\u606F\u53D1\u9001\uFF08\u975E opus \u97F3\u9891\u964D\u7EA7\uFF09");
|
|
36068
36185
|
} else {
|
|
36069
36186
|
let durationMs = Math.round(fileBuffer.length / 3);
|
|
36070
36187
|
try {
|
|
@@ -36077,17 +36194,17 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
36077
36194
|
} catch {
|
|
36078
36195
|
}
|
|
36079
36196
|
const audioKey = await this._uploadAudio(fileBuffer, filename.endsWith(".opus") ? filename : filename.replace(/\.[^.]+$/, ".opus"), durationMs);
|
|
36080
|
-
await this.client.im.message.create({
|
|
36197
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
36081
36198
|
params: { receive_id_type: receiveIdType },
|
|
36082
36199
|
data: { receive_id: safeTarget, msg_type: "audio", content: JSON.stringify({ file_key: audioKey }) }
|
|
36083
|
-
});
|
|
36200
|
+
}), "\u8BED\u97F3\u6761\u53D1\u9001");
|
|
36084
36201
|
}
|
|
36085
36202
|
} else {
|
|
36086
36203
|
const fileKey = await this._uploadFile(fileBuffer, filename);
|
|
36087
|
-
await this.client.im.message.create({
|
|
36204
|
+
this._assertApiOk(await this.client.im.message.create({
|
|
36088
36205
|
params: { receive_id_type: receiveIdType },
|
|
36089
36206
|
data: { receive_id: safeTarget, msg_type: "file", content: JSON.stringify({ file_key: fileKey }) }
|
|
36090
|
-
});
|
|
36207
|
+
}), "\u6587\u4EF6\u6D88\u606F\u53D1\u9001");
|
|
36091
36208
|
}
|
|
36092
36209
|
if (message && mimeType.startsWith("image/")) {
|
|
36093
36210
|
} else if (message) {
|
|
@@ -41245,7 +41362,7 @@ var TTS_IMPL = {
|
|
|
41245
41362
|
if (r.warning) console.warn(`[my-voice] ${r.warning}`);
|
|
41246
41363
|
if (!r.voice) {
|
|
41247
41364
|
throw new TtsConfigError(
|
|
41248
|
-
"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\
|
|
41365
|
+
"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"
|
|
41249
41366
|
);
|
|
41250
41367
|
}
|
|
41251
41368
|
try {
|
|
@@ -41468,7 +41585,7 @@ registry.register({
|
|
|
41468
41585
|
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"
|
|
41469
41586
|
},
|
|
41470
41587
|
channel: { type: "string", enum: ["weixin", "feishu", "discord"], description: "Target channel. Default: current channel." },
|
|
41471
|
-
to: { type: "string", description:
|
|
41588
|
+
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' },
|
|
41472
41589
|
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' },
|
|
41473
41590
|
caption: { type: "string", description: "Optional text to accompany the voice message." }
|
|
41474
41591
|
},
|
|
@@ -41580,7 +41697,8 @@ registry.register({
|
|
|
41580
41697
|
}
|
|
41581
41698
|
return { content: `Voice sent! (${actualEngine}, ${sizeKB.toFixed(0)}KB, ${resolvedChannel})` };
|
|
41582
41699
|
} catch (err) {
|
|
41583
|
-
|
|
41700
|
+
const toHint = args2.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' : "";
|
|
41701
|
+
return { content: `Voice send failed: ${err.message}${toHint}`, isError: true };
|
|
41584
41702
|
}
|
|
41585
41703
|
},
|
|
41586
41704
|
isConcurrencySafe: () => false,
|
|
@@ -44942,6 +45060,7 @@ async function startEngine(config2, opts) {
|
|
|
44942
45060
|
applyFreeTierVideoFixup({ all: () => liveConfig.all(), set: (p, v) => {
|
|
44943
45061
|
void liveConfig.set(p, v);
|
|
44944
45062
|
} });
|
|
45063
|
+
await applyFreeTierVoiceFixup({ all: () => liveConfig.all(), set: (p, v) => liveConfig.set(p, v) });
|
|
44945
45064
|
let provider;
|
|
44946
45065
|
let visionProvider;
|
|
44947
45066
|
let visionChainLabels;
|