engine7 7.1.27 → 7.1.28
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 +2 -2
- package/dist/engine-startup.mjs +228 -225
- package/dist/main.mjs +231 -228
- package/package.json +1 -1
- package/src/memory/everos/python/requirements.txt +2 -2
package/dist/engine-startup.mjs
CHANGED
|
@@ -5747,11 +5747,11 @@ async function readLastConsolidatedAt(memoryDir) {
|
|
|
5747
5747
|
}
|
|
5748
5748
|
}
|
|
5749
5749
|
async function tryAcquireConsolidationLock(memoryDir) {
|
|
5750
|
-
const
|
|
5750
|
+
const path45 = lockPath(memoryDir);
|
|
5751
5751
|
let mtimeMs;
|
|
5752
5752
|
let holderPid;
|
|
5753
5753
|
try {
|
|
5754
|
-
const [s2, raw] = await Promise.all([stat3(
|
|
5754
|
+
const [s2, raw] = await Promise.all([stat3(path45), readFile5(path45, "utf8")]);
|
|
5755
5755
|
mtimeMs = s2.mtimeMs;
|
|
5756
5756
|
const parsed = parseInt(raw.trim(), 10);
|
|
5757
5757
|
holderPid = Number.isFinite(parsed) ? parsed : void 0;
|
|
@@ -5764,10 +5764,10 @@ async function tryAcquireConsolidationLock(memoryDir) {
|
|
|
5764
5764
|
}
|
|
5765
5765
|
}
|
|
5766
5766
|
await mkdir3(memoryDir, { recursive: true });
|
|
5767
|
-
await writeFile4(
|
|
5767
|
+
await writeFile4(path45, String(process.pid));
|
|
5768
5768
|
let verify2;
|
|
5769
5769
|
try {
|
|
5770
|
-
verify2 = await readFile5(
|
|
5770
|
+
verify2 = await readFile5(path45, "utf8");
|
|
5771
5771
|
} catch {
|
|
5772
5772
|
return null;
|
|
5773
5773
|
}
|
|
@@ -5775,15 +5775,15 @@ async function tryAcquireConsolidationLock(memoryDir) {
|
|
|
5775
5775
|
return mtimeMs ?? 0;
|
|
5776
5776
|
}
|
|
5777
5777
|
async function rollbackConsolidationLock(memoryDir, priorMtime) {
|
|
5778
|
-
const
|
|
5778
|
+
const path45 = lockPath(memoryDir);
|
|
5779
5779
|
try {
|
|
5780
5780
|
if (priorMtime === 0) {
|
|
5781
|
-
await unlink(
|
|
5781
|
+
await unlink(path45);
|
|
5782
5782
|
return;
|
|
5783
5783
|
}
|
|
5784
|
-
await writeFile4(
|
|
5784
|
+
await writeFile4(path45, "");
|
|
5785
5785
|
const t = priorMtime / 1e3;
|
|
5786
|
-
await utimes(
|
|
5786
|
+
await utimes(path45, t, t);
|
|
5787
5787
|
} catch (e) {
|
|
5788
5788
|
console.log(`[autoDream] rollback failed: ${e.message} \u2014 next trigger delayed to minHours`);
|
|
5789
5789
|
}
|
|
@@ -6116,15 +6116,15 @@ __export(TodoWriteTool_exports, {
|
|
|
6116
6116
|
loadTodos: () => loadTodos
|
|
6117
6117
|
});
|
|
6118
6118
|
import fs31 from "node:fs";
|
|
6119
|
-
import
|
|
6119
|
+
import path32 from "node:path";
|
|
6120
6120
|
function initTodoStore(stateDir) {
|
|
6121
|
-
todosDir =
|
|
6121
|
+
todosDir = path32.join(stateDir, "todos");
|
|
6122
6122
|
if (!fs31.existsSync(todosDir)) {
|
|
6123
6123
|
fs31.mkdirSync(todosDir, { recursive: true });
|
|
6124
6124
|
}
|
|
6125
6125
|
}
|
|
6126
6126
|
function todoFilePath(sessionId) {
|
|
6127
|
-
return
|
|
6127
|
+
return path32.join(todosDir, `${sessionId}.json`);
|
|
6128
6128
|
}
|
|
6129
6129
|
function loadTodos(sessionId) {
|
|
6130
6130
|
if (!todosDir) return [];
|
|
@@ -6220,15 +6220,15 @@ __export(tasks_exports, {
|
|
|
6220
6220
|
updateTask: () => updateTask
|
|
6221
6221
|
});
|
|
6222
6222
|
import * as fs33 from "node:fs";
|
|
6223
|
-
import * as
|
|
6223
|
+
import * as path34 from "node:path";
|
|
6224
6224
|
function sanitizePathComponent2(input) {
|
|
6225
6225
|
return input.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
6226
6226
|
}
|
|
6227
6227
|
function getTasksDir2(stateDir, listId) {
|
|
6228
|
-
return
|
|
6228
|
+
return path34.join(stateDir, "tasks", sanitizePathComponent2(listId));
|
|
6229
6229
|
}
|
|
6230
6230
|
function getTaskPath(stateDir, listId, taskId) {
|
|
6231
|
-
return
|
|
6231
|
+
return path34.join(getTasksDir2(stateDir, listId), `${sanitizePathComponent2(taskId)}.json`);
|
|
6232
6232
|
}
|
|
6233
6233
|
function ensureTasksDir2(stateDir, listId) {
|
|
6234
6234
|
const dir = getTasksDir2(stateDir, listId);
|
|
@@ -6236,7 +6236,7 @@ function ensureTasksDir2(stateDir, listId) {
|
|
|
6236
6236
|
return dir;
|
|
6237
6237
|
}
|
|
6238
6238
|
function getHighWaterMarkPath(stateDir, listId) {
|
|
6239
|
-
return
|
|
6239
|
+
return path34.join(getTasksDir2(stateDir, listId), HIGH_WATER_MARK_FILE);
|
|
6240
6240
|
}
|
|
6241
6241
|
function readHighWaterMark(stateDir, listId) {
|
|
6242
6242
|
try {
|
|
@@ -6442,7 +6442,7 @@ __export(read_exports, {
|
|
|
6442
6442
|
readFileState: () => readFileState
|
|
6443
6443
|
});
|
|
6444
6444
|
import * as fs34 from "node:fs";
|
|
6445
|
-
import * as
|
|
6445
|
+
import * as path35 from "node:path";
|
|
6446
6446
|
function isBlockedDevicePath(filePath) {
|
|
6447
6447
|
if (BLOCKED_DEVICE_PATHS.has(filePath)) return true;
|
|
6448
6448
|
if (filePath.startsWith("/proc/") && (filePath.endsWith("/fd/0") || filePath.endsWith("/fd/1") || filePath.endsWith("/fd/2"))) return true;
|
|
@@ -6621,7 +6621,7 @@ Usage:
|
|
|
6621
6621
|
return { content: `\u6587\u4EF6\u4E0D\u5B58\u5728: ${filePath}`, isError: true };
|
|
6622
6622
|
}
|
|
6623
6623
|
const stat4 = fs34.statSync(filePath);
|
|
6624
|
-
const baseName =
|
|
6624
|
+
const baseName = path35.basename(filePath).toUpperCase();
|
|
6625
6625
|
if (BLOCKED_BASENAMES.has(baseName)) {
|
|
6626
6626
|
return { content: `\u8BBE\u5907\u6587\u4EF6\u4E0D\u652F\u6301\u8BFB\u53D6: ${filePath}`, isError: true };
|
|
6627
6627
|
}
|
|
@@ -6631,7 +6631,7 @@ Usage:
|
|
|
6631
6631
|
if (stat4.isDirectory()) {
|
|
6632
6632
|
const entries = fs34.readdirSync(filePath);
|
|
6633
6633
|
const items = entries.map((e) => {
|
|
6634
|
-
const full =
|
|
6634
|
+
const full = path35.join(filePath, e);
|
|
6635
6635
|
try {
|
|
6636
6636
|
const s2 = fs34.statSync(full);
|
|
6637
6637
|
return s2.isDirectory() ? `${e}/` : e;
|
|
@@ -6642,7 +6642,7 @@ Usage:
|
|
|
6642
6642
|
return { content: `\u76EE\u5F55 (${entries.length} \u9879):
|
|
6643
6643
|
${items.join("\n")}` };
|
|
6644
6644
|
}
|
|
6645
|
-
const ext =
|
|
6645
|
+
const ext = path35.extname(filePath).toLowerCase();
|
|
6646
6646
|
if (BINARY_EXTENSIONS.has(ext)) {
|
|
6647
6647
|
return { content: `\u4E8C\u8FDB\u5236\u6587\u4EF6\u4E0D\u652F\u6301\u8BFB\u53D6 (${ext}): ${filePath}`, isError: true };
|
|
6648
6648
|
}
|
|
@@ -6691,7 +6691,7 @@ ${result}` : result };
|
|
|
6691
6691
|
// src/tools/write.ts
|
|
6692
6692
|
var write_exports = {};
|
|
6693
6693
|
import * as fs35 from "node:fs";
|
|
6694
|
-
import * as
|
|
6694
|
+
import * as path36 from "node:path";
|
|
6695
6695
|
function isBlockedPath(filePath) {
|
|
6696
6696
|
return BLOCKED_PATTERNS.some((p2) => p2.test(filePath));
|
|
6697
6697
|
}
|
|
@@ -6835,7 +6835,7 @@ Usage:
|
|
|
6835
6835
|
}
|
|
6836
6836
|
}
|
|
6837
6837
|
}
|
|
6838
|
-
const dir =
|
|
6838
|
+
const dir = path36.dirname(filePath);
|
|
6839
6839
|
try {
|
|
6840
6840
|
fs35.mkdirSync(dir, { recursive: true });
|
|
6841
6841
|
} catch (e) {
|
|
@@ -6871,7 +6871,7 @@ ${simpleDiff(oldContent, content)}`;
|
|
|
6871
6871
|
// src/tools/edit.ts
|
|
6872
6872
|
var edit_exports = {};
|
|
6873
6873
|
import * as fs36 from "node:fs";
|
|
6874
|
-
import * as
|
|
6874
|
+
import * as path37 from "node:path";
|
|
6875
6875
|
function normalizeQuotes(str) {
|
|
6876
6876
|
return str.replaceAll(LEFT_SINGLE_CURLY, "'").replaceAll(RIGHT_SINGLE_CURLY, "'").replaceAll(LEFT_DOUBLE_CURLY, '"').replaceAll(RIGHT_DOUBLE_CURLY, '"');
|
|
6877
6877
|
}
|
|
@@ -7034,7 +7034,7 @@ Usage:
|
|
|
7034
7034
|
} catch (e) {
|
|
7035
7035
|
if (e.code === "ENOENT") {
|
|
7036
7036
|
if (oldString === "") {
|
|
7037
|
-
const dir =
|
|
7037
|
+
const dir = path37.dirname(filePath);
|
|
7038
7038
|
fs36.mkdirSync(dir, { recursive: true });
|
|
7039
7039
|
fs36.writeFileSync(filePath, newString, "utf-8");
|
|
7040
7040
|
readFileState.set(filePath, { timestamp: fs36.statSync(filePath).mtimeMs });
|
|
@@ -7114,7 +7114,7 @@ ${diffView}`
|
|
|
7114
7114
|
// src/tools/glob.ts
|
|
7115
7115
|
var glob_exports = {};
|
|
7116
7116
|
import * as fs37 from "node:fs";
|
|
7117
|
-
import * as
|
|
7117
|
+
import * as path38 from "node:path";
|
|
7118
7118
|
function globMatch(pattern, filename) {
|
|
7119
7119
|
const regexStr = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "{{GLOBSTAR}}").replace(/\*/g, "[^/]*").replace(/\?/g, "[^/]").replace(/\{\{GLOBSTAR\}\}/g, ".*");
|
|
7120
7120
|
try {
|
|
@@ -7140,12 +7140,12 @@ function findFiles(dir, pattern, limit, baseDir) {
|
|
|
7140
7140
|
}
|
|
7141
7141
|
for (const entry of entries) {
|
|
7142
7142
|
if (truncated) return;
|
|
7143
|
-
const fullPath =
|
|
7143
|
+
const fullPath = path38.join(currentDir, entry.name);
|
|
7144
7144
|
if (entry.isDirectory()) {
|
|
7145
7145
|
if (VCS_DIRS.has(entry.name)) continue;
|
|
7146
7146
|
walk(fullPath);
|
|
7147
7147
|
} else if (entry.isFile()) {
|
|
7148
|
-
const relativePath =
|
|
7148
|
+
const relativePath = path38.relative(baseDir, fullPath).replace(/\\/g, "/");
|
|
7149
7149
|
const patternsToTry = [pattern];
|
|
7150
7150
|
if (pattern.startsWith("**/")) {
|
|
7151
7151
|
patternsToTry.push(pattern.slice(3));
|
|
@@ -7172,7 +7172,7 @@ function findFiles(dir, pattern, limit, baseDir) {
|
|
|
7172
7172
|
};
|
|
7173
7173
|
}
|
|
7174
7174
|
function toRelativePath(absolutePath, cwd) {
|
|
7175
|
-
if (absolutePath.startsWith(cwd +
|
|
7175
|
+
if (absolutePath.startsWith(cwd + path38.sep)) {
|
|
7176
7176
|
return absolutePath.slice(cwd.length + 1);
|
|
7177
7177
|
}
|
|
7178
7178
|
return absolutePath;
|
|
@@ -7233,7 +7233,7 @@ ${filenames.join("\n")}${truncatedNote}`
|
|
|
7233
7233
|
// src/tools/grep.ts
|
|
7234
7234
|
var grep_exports = {};
|
|
7235
7235
|
import { execFile as execFile2 } from "node:child_process";
|
|
7236
|
-
import * as
|
|
7236
|
+
import * as path39 from "node:path";
|
|
7237
7237
|
function ripGrep(args, searchPath, signal) {
|
|
7238
7238
|
return new Promise((resolve10) => {
|
|
7239
7239
|
const fullArgs = [...args, searchPath];
|
|
@@ -7265,7 +7265,7 @@ function applyHeadLimit(items, limit, offset = 0) {
|
|
|
7265
7265
|
};
|
|
7266
7266
|
}
|
|
7267
7267
|
function toRelativePath2(absolutePath, cwd) {
|
|
7268
|
-
if (absolutePath.startsWith(cwd +
|
|
7268
|
+
if (absolutePath.startsWith(cwd + path39.sep)) {
|
|
7269
7269
|
return absolutePath.slice(cwd.length + 1);
|
|
7270
7270
|
}
|
|
7271
7271
|
if (absolutePath.startsWith(cwd)) {
|
|
@@ -9934,7 +9934,7 @@ var init_web_fetch = __esm({
|
|
|
9934
9934
|
|
|
9935
9935
|
// src/cron/tasks.ts
|
|
9936
9936
|
import fs38 from "node:fs";
|
|
9937
|
-
import
|
|
9937
|
+
import path40 from "node:path";
|
|
9938
9938
|
import crypto5 from "node:crypto";
|
|
9939
9939
|
function getStorageDir() {
|
|
9940
9940
|
return storageDir;
|
|
@@ -9989,7 +9989,7 @@ function readTasksFromDisk() {
|
|
|
9989
9989
|
}
|
|
9990
9990
|
}
|
|
9991
9991
|
async function writeTasksToDisk(tasks2) {
|
|
9992
|
-
const lockPath2 =
|
|
9992
|
+
const lockPath2 = path40.join(storageDir, "tasks.json.lock");
|
|
9993
9993
|
await withFileLock(lockPath2, () => {
|
|
9994
9994
|
const store = {
|
|
9995
9995
|
version: 1,
|
|
@@ -10001,7 +10001,7 @@ async function writeTasksToDisk(tasks2) {
|
|
|
10001
10001
|
}
|
|
10002
10002
|
function initTaskStore(dir) {
|
|
10003
10003
|
storageDir = dir;
|
|
10004
|
-
tasksFilePath =
|
|
10004
|
+
tasksFilePath = path40.join(dir, "tasks.json");
|
|
10005
10005
|
if (!fs38.existsSync(dir)) {
|
|
10006
10006
|
fs38.mkdirSync(dir, { recursive: true });
|
|
10007
10007
|
}
|
|
@@ -10915,9 +10915,9 @@ async function executeAndDeliver(task, now, deps) {
|
|
|
10915
10915
|
let filePath = promptText.slice(1).trim();
|
|
10916
10916
|
try {
|
|
10917
10917
|
const fs42 = await import("fs");
|
|
10918
|
-
const
|
|
10919
|
-
if (!
|
|
10920
|
-
filePath =
|
|
10918
|
+
const path45 = await import("path");
|
|
10919
|
+
if (!path45.isAbsolute(filePath)) {
|
|
10920
|
+
filePath = path45.join(deps.sessions["config"].stateDir, filePath);
|
|
10921
10921
|
}
|
|
10922
10922
|
promptText = fs42.readFileSync(filePath, "utf-8");
|
|
10923
10923
|
console.log(`[cron] Loaded prompt from ${filePath} (${promptText.length} chars)`);
|
|
@@ -10946,15 +10946,15 @@ async function executeAndDeliver(task, now, deps) {
|
|
|
10946
10946
|
let finalResult = result;
|
|
10947
10947
|
if (task.postProcess) {
|
|
10948
10948
|
try {
|
|
10949
|
-
const
|
|
10949
|
+
const path45 = await import("path");
|
|
10950
10950
|
const fs42 = await import("fs");
|
|
10951
10951
|
let scriptPath = task.postProcess;
|
|
10952
|
-
if (!
|
|
10953
|
-
scriptPath =
|
|
10952
|
+
if (!path45.isAbsolute(scriptPath)) {
|
|
10953
|
+
scriptPath = path45.join(deps.sessions["config"].stateDir, scriptPath);
|
|
10954
10954
|
}
|
|
10955
|
-
const resultsDirTmp =
|
|
10955
|
+
const resultsDirTmp = path45.join(getStorageDir(), "results");
|
|
10956
10956
|
fs42.mkdirSync(resultsDirTmp, { recursive: true });
|
|
10957
|
-
const inputFile =
|
|
10957
|
+
const inputFile = path45.join(resultsDirTmp, `${task.id}.input.txt`);
|
|
10958
10958
|
fs42.writeFileSync(inputFile, result, "utf-8");
|
|
10959
10959
|
const { execFile: execFile3 } = await import("child_process");
|
|
10960
10960
|
await new Promise((resolve10) => {
|
|
@@ -10983,10 +10983,10 @@ async function executeAndDeliver(task, now, deps) {
|
|
|
10983
10983
|
}
|
|
10984
10984
|
try {
|
|
10985
10985
|
const fs42 = await import("fs");
|
|
10986
|
-
const
|
|
10987
|
-
const resultsDir =
|
|
10986
|
+
const path45 = await import("path");
|
|
10987
|
+
const resultsDir = path45.join(getStorageDir(), "results");
|
|
10988
10988
|
fs42.mkdirSync(resultsDir, { recursive: true });
|
|
10989
|
-
const resultFile =
|
|
10989
|
+
const resultFile = path45.join(resultsDir, `${task.id}.json`);
|
|
10990
10990
|
fs42.writeFileSync(resultFile, JSON.stringify({
|
|
10991
10991
|
taskId: task.id,
|
|
10992
10992
|
description: task.description,
|
|
@@ -11235,13 +11235,13 @@ function registerCronTools() {
|
|
|
11235
11235
|
},
|
|
11236
11236
|
handler: async (args) => {
|
|
11237
11237
|
const fs42 = await import("fs");
|
|
11238
|
-
const
|
|
11239
|
-
const resultsDir =
|
|
11238
|
+
const path45 = await import("path");
|
|
11239
|
+
const resultsDir = path45.join(getStorageDir(), "results");
|
|
11240
11240
|
if (!fs42.existsSync(resultsDir)) {
|
|
11241
11241
|
return { content: "\u6682\u65E0cron\u6267\u884C\u7ED3\u679C" };
|
|
11242
11242
|
}
|
|
11243
11243
|
if (args.task_id) {
|
|
11244
|
-
const file =
|
|
11244
|
+
const file = path45.join(resultsDir, `${args.task_id}.json`);
|
|
11245
11245
|
if (!fs42.existsSync(file)) {
|
|
11246
11246
|
return { content: `\u4EFB\u52A1 ${args.task_id} \u6682\u65E0\u6267\u884C\u7ED3\u679C`, isError: true };
|
|
11247
11247
|
}
|
|
@@ -11257,7 +11257,7 @@ ${data.result}` };
|
|
|
11257
11257
|
return { content: "\u6682\u65E0cron\u6267\u884C\u7ED3\u679C" };
|
|
11258
11258
|
}
|
|
11259
11259
|
const results = files.map((f2) => {
|
|
11260
|
-
const data = JSON.parse(fs42.readFileSync(
|
|
11260
|
+
const data = JSON.parse(fs42.readFileSync(path45.join(resultsDir, f2), "utf-8"));
|
|
11261
11261
|
return `### ${data.description} (${data.taskId.slice(0, 8)})
|
|
11262
11262
|
\u6267\u884C: ${data.executedAt} | \u7B2C${data.runCount}\u6B21
|
|
11263
11263
|
${data.result.slice(0, 500)}${data.result.length > 500 ? "..." : ""}`;
|
|
@@ -11311,6 +11311,7 @@ var init_tools = __esm({
|
|
|
11311
11311
|
|
|
11312
11312
|
// src/tools/wechat/wx-query.ts
|
|
11313
11313
|
var wx_query_exports = {};
|
|
11314
|
+
import { join as join34 } from "node:path";
|
|
11314
11315
|
function getDescription() {
|
|
11315
11316
|
return `\u67E5\u8BE2\u7FC0\u54E5\u7684\u5FAE\u4FE1\u6D88\u606F\uFF08\u7F13\u5B58\u89E3\u5BC6\u540E\u7684\u672C\u5730\u6570\u636E\u5E93\uFF09\u3002
|
|
11316
11317
|
|
|
@@ -11339,13 +11340,14 @@ function getDescription() {
|
|
|
11339
11340
|
\u26A0\uFE0F \u9690\u79C1\u6CE8\u610F: \u79C1\u804A\u6D88\u606F\u4E0D\u66B4\u9732\u7ED9\u5176\u4ED6\u4EBA\uFF0C\u4EC5\u7528\u4E8E\u7FC0\u54E5\u81EA\u5DF1\u7684\u67E5\u8BE2\u3002
|
|
11340
11341
|
\u5982\u679C\u67E5\u8BE2\u5230\u79C1\u804A\u5185\u5BB9\uFF0C\u4EC5\u544A\u77E5\u7FC0\u54E5\u672C\u4EBA\u3002`;
|
|
11341
11342
|
}
|
|
11342
|
-
var SCRIPT, PYTHON;
|
|
11343
|
+
var STATE_DIR, SCRIPT, PYTHON;
|
|
11343
11344
|
var init_wx_query = __esm({
|
|
11344
11345
|
"src/tools/wechat/wx-query.ts"() {
|
|
11345
11346
|
"use strict";
|
|
11346
11347
|
init_registry();
|
|
11347
11348
|
init_live();
|
|
11348
|
-
|
|
11349
|
+
STATE_DIR = process.env.ENGINE7_STATE_DIR || process.env.OPENCLAW_STATE_DIR || join34(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
|
|
11350
|
+
SCRIPT = join34(STATE_DIR, "engine", "src", "tools", "wechat", "wx_query.py");
|
|
11349
11351
|
PYTHON = "python3";
|
|
11350
11352
|
registry.register({
|
|
11351
11353
|
name: "wx_query",
|
|
@@ -11419,7 +11421,7 @@ __export(manager_exports, {
|
|
|
11419
11421
|
McpManager: () => McpManager
|
|
11420
11422
|
});
|
|
11421
11423
|
import * as fs40 from "node:fs";
|
|
11422
|
-
import * as
|
|
11424
|
+
import * as path42 from "node:path";
|
|
11423
11425
|
import { Client as Client3 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
11424
11426
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
11425
11427
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
|
@@ -11452,9 +11454,9 @@ function convertInputSchema(inputSchema) {
|
|
|
11452
11454
|
}
|
|
11453
11455
|
function persistBinary(base64Data, mimeType, persistId) {
|
|
11454
11456
|
const ext = mimeType?.split("/")[1] || "bin";
|
|
11455
|
-
const dir =
|
|
11457
|
+
const dir = path42.join(process.env.ENGINE_STATE_DIR || ".engine", "mcp-blobs");
|
|
11456
11458
|
fs40.mkdirSync(dir, { recursive: true });
|
|
11457
|
-
const filepath =
|
|
11459
|
+
const filepath = path42.join(dir, `${persistId}.${ext}`);
|
|
11458
11460
|
try {
|
|
11459
11461
|
const buf = Buffer.from(base64Data, "base64");
|
|
11460
11462
|
fs40.writeFileSync(filepath, buf);
|
|
@@ -11791,7 +11793,7 @@ __export(resources_exports, {
|
|
|
11791
11793
|
registerMcpResourceTools: () => registerMcpResourceTools,
|
|
11792
11794
|
unregisterMcpResourceTools: () => unregisterMcpResourceTools
|
|
11793
11795
|
});
|
|
11794
|
-
import * as
|
|
11796
|
+
import * as path43 from "node:path";
|
|
11795
11797
|
function registerMcpResourceTools(manager) {
|
|
11796
11798
|
mcpManagerRef = manager;
|
|
11797
11799
|
registry.register(listResourcesTool);
|
|
@@ -11809,7 +11811,7 @@ var init_resources = __esm({
|
|
|
11809
11811
|
"use strict";
|
|
11810
11812
|
init_registry();
|
|
11811
11813
|
MAX_RESULT_CHARS2 = 1e5;
|
|
11812
|
-
MEDIA_DIR = process.env.ENGINE_MEDIA_DIR ||
|
|
11814
|
+
MEDIA_DIR = process.env.ENGINE_MEDIA_DIR || path43.join(process.env.ENGINE_STATE_DIR || ".engine", "media", "inbound");
|
|
11813
11815
|
MCP_LIST_RESOURCES_TOOL = "mcp__list_resources";
|
|
11814
11816
|
MCP_READ_RESOURCE_TOOL = "mcp__read_resource";
|
|
11815
11817
|
mcpManagerRef = null;
|
|
@@ -12052,7 +12054,7 @@ __export(reply_blocklist_exports, {
|
|
|
12052
12054
|
isUserBlocked: () => isUserBlocked
|
|
12053
12055
|
});
|
|
12054
12056
|
import { readFileSync as readFileSync26, writeFileSync as writeFileSync15, existsSync as existsSync24 } from "node:fs";
|
|
12055
|
-
import { join as
|
|
12057
|
+
import { join as join38 } from "node:path";
|
|
12056
12058
|
function ensureLoaded(workspace, configIds) {
|
|
12057
12059
|
if (loaded) return;
|
|
12058
12060
|
if (configIds?.length) {
|
|
@@ -12060,10 +12062,10 @@ function ensureLoaded(workspace, configIds) {
|
|
|
12060
12062
|
if (!state.blockedUserIds.includes(id)) state.blockedUserIds.push(id);
|
|
12061
12063
|
}
|
|
12062
12064
|
}
|
|
12063
|
-
const
|
|
12065
|
+
const path45 = join38(workspace, ".reply-blocklist.json");
|
|
12064
12066
|
try {
|
|
12065
|
-
if (existsSync24(
|
|
12066
|
-
const raw = readFileSync26(
|
|
12067
|
+
if (existsSync24(path45)) {
|
|
12068
|
+
const raw = readFileSync26(path45, "utf-8");
|
|
12067
12069
|
const parsed = JSON.parse(raw);
|
|
12068
12070
|
if (parsed.blockedUserIds) {
|
|
12069
12071
|
for (const id of parsed.blockedUserIds) {
|
|
@@ -12079,9 +12081,9 @@ function ensureLoaded(workspace, configIds) {
|
|
|
12079
12081
|
loaded = true;
|
|
12080
12082
|
}
|
|
12081
12083
|
function save(workspace) {
|
|
12082
|
-
const
|
|
12084
|
+
const path45 = join38(workspace, ".reply-blocklist.json");
|
|
12083
12085
|
try {
|
|
12084
|
-
writeFileSync15(
|
|
12086
|
+
writeFileSync15(path45, JSON.stringify(state, null, 2), "utf-8");
|
|
12085
12087
|
} catch (err) {
|
|
12086
12088
|
console.warn(`[reply-blocklist] Failed to save: ${err.message}`);
|
|
12087
12089
|
}
|
|
@@ -12678,7 +12680,7 @@ var init_cognifold_intent_watcher = __esm({
|
|
|
12678
12680
|
});
|
|
12679
12681
|
|
|
12680
12682
|
// src/engine-startup.ts
|
|
12681
|
-
import * as
|
|
12683
|
+
import * as path44 from "node:path";
|
|
12682
12684
|
import * as fs41 from "node:fs";
|
|
12683
12685
|
import { fileURLToPath } from "node:url";
|
|
12684
12686
|
|
|
@@ -14022,11 +14024,11 @@ var DiscordAdapter = class _DiscordAdapter {
|
|
|
14022
14024
|
/** 发送媒体附件(图片/文件/音频)— discord.js channel.send({ files }) */
|
|
14023
14025
|
async sendFile(target, message, attachment) {
|
|
14024
14026
|
const fs42 = await import("node:fs");
|
|
14025
|
-
const
|
|
14027
|
+
const path45 = await import("node:path");
|
|
14026
14028
|
if (!fs42.existsSync(attachment.path)) {
|
|
14027
14029
|
throw new Error(`File not found: ${attachment.path}`);
|
|
14028
14030
|
}
|
|
14029
|
-
const filename = attachment.filename ||
|
|
14031
|
+
const filename = attachment.filename || path45.basename(attachment.path);
|
|
14030
14032
|
const fileBuffer = fs42.readFileSync(attachment.path);
|
|
14031
14033
|
const filePayload = {
|
|
14032
14034
|
attachment: fileBuffer,
|
|
@@ -14468,11 +14470,11 @@ var FeishuAdapter = class _FeishuAdapter {
|
|
|
14468
14470
|
/** 发送媒体附件(图片/文件) */
|
|
14469
14471
|
async sendFile(target, message, attachment) {
|
|
14470
14472
|
const fs42 = await import("node:fs");
|
|
14471
|
-
const
|
|
14473
|
+
const path45 = await import("node:path");
|
|
14472
14474
|
if (!fs42.existsSync(attachment.path)) {
|
|
14473
14475
|
throw new Error(`File not found: ${attachment.path}`);
|
|
14474
14476
|
}
|
|
14475
|
-
const filename = attachment.filename ||
|
|
14477
|
+
const filename = attachment.filename || path45.basename(attachment.path);
|
|
14476
14478
|
const fileBuffer = fs42.readFileSync(attachment.path);
|
|
14477
14479
|
const receiveIdType = target.startsWith("ou_") ? "open_id" : "chat_id";
|
|
14478
14480
|
const mimeType = attachment.mimeType || "application/octet-stream";
|
|
@@ -15304,7 +15306,7 @@ var WechatAdapter = class {
|
|
|
15304
15306
|
this.config = config;
|
|
15305
15307
|
this.baseUrl = config.baseUrl?.replace(/\/$/, "") || ILINK_BASE_URL;
|
|
15306
15308
|
this.cdnBaseUrl = config.cdnBaseUrl?.replace(/\/$/, "") || WEIXIN_CDN_BASE_URL;
|
|
15307
|
-
this.stateDir = config.stateDir || path4.join(os.homedir?.() || "/tmp", ".
|
|
15309
|
+
this.stateDir = config.stateDir || path4.join(os.homedir?.() || "/tmp", ".engine7");
|
|
15308
15310
|
if (!fs5.existsSync(this.stateDir)) fs5.mkdirSync(this.stateDir, { recursive: true });
|
|
15309
15311
|
}
|
|
15310
15312
|
// --- ChannelAdapter interface ---
|
|
@@ -18553,8 +18555,8 @@ ${ep.episode || ep.summary}`,
|
|
|
18553
18555
|
// src/handle-query.ts
|
|
18554
18556
|
init_paths();
|
|
18555
18557
|
import { readFileSync as readFileSync15, existsSync as existsSync12 } from "node:fs";
|
|
18556
|
-
import { join as join20 } from "node:path";
|
|
18557
|
-
import
|
|
18558
|
+
import { join as join20, resolve as resolve6 } from "node:path";
|
|
18559
|
+
import * as path13 from "node:path";
|
|
18558
18560
|
var contactMap = null;
|
|
18559
18561
|
var externalChanWhitelist = null;
|
|
18560
18562
|
function loadContactMap(workspace) {
|
|
@@ -18622,18 +18624,18 @@ function truncate(s2, maxLen) {
|
|
|
18622
18624
|
}
|
|
18623
18625
|
var externalChanRulesCache = null;
|
|
18624
18626
|
function loadExternalChanRules(workspace) {
|
|
18625
|
-
const
|
|
18626
|
-
if (externalChanRulesCache && externalChanRulesCache.path ===
|
|
18627
|
+
const path45 = join20(workspace, "prompts", "external-chan-rules.md");
|
|
18628
|
+
if (externalChanRulesCache && externalChanRulesCache.path === path45) return externalChanRulesCache;
|
|
18627
18629
|
let content = "";
|
|
18628
|
-
if (existsSync12(
|
|
18630
|
+
if (existsSync12(path45)) {
|
|
18629
18631
|
try {
|
|
18630
|
-
content = readFileSync15(
|
|
18632
|
+
content = readFileSync15(path45, "utf-8").trim();
|
|
18631
18633
|
} catch (e) {
|
|
18632
18634
|
console.warn(`[external-chan-rules] Failed to load: ${e}`);
|
|
18633
18635
|
}
|
|
18634
18636
|
}
|
|
18635
|
-
externalChanRulesCache = { path:
|
|
18636
|
-
console.log(`[external-chan-rules] Loaded ${content.length} chars from ${
|
|
18637
|
+
externalChanRulesCache = { path: path45, content };
|
|
18638
|
+
console.log(`[external-chan-rules] Loaded ${content.length} chars from ${path45}`);
|
|
18637
18639
|
return externalChanRulesCache;
|
|
18638
18640
|
}
|
|
18639
18641
|
function getExternalChanRulesBlock(inboundMeta, workspace) {
|
|
@@ -18902,8 +18904,8 @@ ${text}` : text });
|
|
|
18902
18904
|
console.log(`[${sessionId}] >>> query start (${messages.length} msgs in history)`);
|
|
18903
18905
|
try {
|
|
18904
18906
|
const { writeFileSync: writeFileSync17 } = await import("node:fs");
|
|
18905
|
-
const { join:
|
|
18906
|
-
const contextPath =
|
|
18907
|
+
const { join: join40 } = await import("node:path");
|
|
18908
|
+
const contextPath = join40(workspace, ".context-debug.txt");
|
|
18907
18909
|
const lines = [
|
|
18908
18910
|
"=== Context Debug ===",
|
|
18909
18911
|
`Time: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
@@ -19288,7 +19290,7 @@ stack: ${err.stack ?? "(none)"}`);
|
|
|
19288
19290
|
}
|
|
19289
19291
|
} catch (err) {
|
|
19290
19292
|
try {
|
|
19291
|
-
(await import("node:fs")).appendFileSync("
|
|
19293
|
+
(await import("node:fs")).appendFileSync(join20(process.env.ENGINE7_STATE_DIR || process.env.OPENCLAW_STATE_DIR || path13.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7"), "logs", "autoDream-debug.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] [handle-query] autoDream trigger TRY-CATCH: ${err.message}
|
|
19292
19294
|
stack: ${err.stack ?? "(none)"}
|
|
19293
19295
|
`);
|
|
19294
19296
|
} catch {
|
|
@@ -19986,16 +19988,16 @@ var MessageDispatcher = class {
|
|
|
19986
19988
|
};
|
|
19987
19989
|
|
|
19988
19990
|
// src/cli-startup.ts
|
|
19989
|
-
import * as
|
|
19991
|
+
import * as path14 from "node:path";
|
|
19990
19992
|
import * as fs13 from "node:fs";
|
|
19991
19993
|
import * as readline2 from "node:readline";
|
|
19992
19994
|
function getDailyLogPath(stateDir) {
|
|
19993
19995
|
const dateStr = (/* @__PURE__ */ new Date()).toLocaleDateString("sv-SE", { timeZone: "Asia/Shanghai" });
|
|
19994
|
-
return
|
|
19996
|
+
return path14.join(stateDir, "logs", `engine-${dateStr}.log`);
|
|
19995
19997
|
}
|
|
19996
19998
|
function setupFileLogging(stateDir) {
|
|
19997
19999
|
const LOG_PATH = getDailyLogPath(stateDir);
|
|
19998
|
-
fs13.mkdirSync(
|
|
20000
|
+
fs13.mkdirSync(path14.join(stateDir, "logs"), { recursive: true });
|
|
19999
20001
|
const logStream = fs13.createWriteStream(LOG_PATH, { flags: "a" });
|
|
20000
20002
|
logStream.on("error", (err) => console.error(`[log] Write error: ${err.message}`));
|
|
20001
20003
|
function ts() {
|
|
@@ -20087,7 +20089,7 @@ function startCliLoop(deps, cliConfig, channelManager, dispatcher) {
|
|
|
20087
20089
|
|
|
20088
20090
|
// src/session/session-history.ts
|
|
20089
20091
|
import fs14 from "node:fs";
|
|
20090
|
-
import
|
|
20092
|
+
import path15 from "node:path";
|
|
20091
20093
|
var BEIJING_OFFSET_MS = 8 * 36e5;
|
|
20092
20094
|
var INJECTED_CONTENT_PATTERNS = [
|
|
20093
20095
|
/【定时心跳】/,
|
|
@@ -20139,10 +20141,10 @@ function scopeMainJsonlPaths(sessions) {
|
|
|
20139
20141
|
let latestArchive = null;
|
|
20140
20142
|
if (current) {
|
|
20141
20143
|
try {
|
|
20142
|
-
const dir =
|
|
20143
|
-
const base =
|
|
20144
|
+
const dir = path15.dirname(current);
|
|
20145
|
+
const base = path15.basename(current);
|
|
20144
20146
|
const archives = fs14.readdirSync(dir).filter((f2) => f2.startsWith(base + ".archived.")).sort();
|
|
20145
|
-
if (archives.length > 0) latestArchive =
|
|
20147
|
+
if (archives.length > 0) latestArchive = path15.join(dir, archives[archives.length - 1]);
|
|
20146
20148
|
} catch {
|
|
20147
20149
|
}
|
|
20148
20150
|
}
|
|
@@ -20389,7 +20391,7 @@ ${basePrompt}`;
|
|
|
20389
20391
|
|
|
20390
20392
|
// src/nudge/plugin.ts
|
|
20391
20393
|
import fs17 from "node:fs";
|
|
20392
|
-
import
|
|
20394
|
+
import path18 from "node:path";
|
|
20393
20395
|
|
|
20394
20396
|
// src/nudge/judge.ts
|
|
20395
20397
|
function shouldNudge(task, taskState, cfg) {
|
|
@@ -20558,10 +20560,10 @@ function formatDuration2(ms) {
|
|
|
20558
20560
|
|
|
20559
20561
|
// src/nudge/session-state-reader.ts
|
|
20560
20562
|
import fs15 from "node:fs";
|
|
20561
|
-
import
|
|
20563
|
+
import path16 from "node:path";
|
|
20562
20564
|
function parseSessionStateFull(workspace, sessionStateFile) {
|
|
20563
20565
|
const stateFile = sessionStateFile || "SESSION-STATE.md";
|
|
20564
|
-
const statePath =
|
|
20566
|
+
const statePath = path16.isAbsolute(stateFile) ? stateFile : path16.join(workspace, stateFile);
|
|
20565
20567
|
let content;
|
|
20566
20568
|
try {
|
|
20567
20569
|
content = fs15.readFileSync(statePath, "utf-8");
|
|
@@ -20616,13 +20618,13 @@ function taskIdFromTitle(title) {
|
|
|
20616
20618
|
|
|
20617
20619
|
// src/calendar/db.ts
|
|
20618
20620
|
import { DatabaseSync } from "node:sqlite";
|
|
20619
|
-
import * as
|
|
20621
|
+
import * as path17 from "node:path";
|
|
20620
20622
|
import * as fs16 from "node:fs";
|
|
20621
20623
|
var TZ_OFFSET_MS = 8 * 60 * 60 * 1e3;
|
|
20622
20624
|
function openDb(workspace) {
|
|
20623
|
-
const dir =
|
|
20625
|
+
const dir = path17.join(workspace, ".calendar");
|
|
20624
20626
|
fs16.mkdirSync(dir, { recursive: true });
|
|
20625
|
-
const dbPath =
|
|
20627
|
+
const dbPath = path17.join(dir, "calendar.db");
|
|
20626
20628
|
const db = new DatabaseSync(dbPath);
|
|
20627
20629
|
db.exec("PRAGMA journal_mode=WAL");
|
|
20628
20630
|
db.exec(`CREATE TABLE IF NOT EXISTS events (
|
|
@@ -20711,7 +20713,7 @@ var NudgePlugin = class {
|
|
|
20711
20713
|
provider;
|
|
20712
20714
|
model;
|
|
20713
20715
|
loadPrompt(workspace, promptFile) {
|
|
20714
|
-
const promptPath = promptFile ?
|
|
20716
|
+
const promptPath = promptFile ? path18.isAbsolute(promptFile) ? promptFile : path18.join(workspace, promptFile) : path18.join(workspace, "prompts", "nudge-prompt.md");
|
|
20715
20717
|
try {
|
|
20716
20718
|
const content = fs17.readFileSync(promptPath, "utf-8").trim();
|
|
20717
20719
|
if (content) {
|
|
@@ -20860,8 +20862,8 @@ var NudgePlugin = class {
|
|
|
20860
20862
|
if (!isWaiting) {
|
|
20861
20863
|
return { outcome: { outcome: "success" } };
|
|
20862
20864
|
}
|
|
20863
|
-
const nudgeDir =
|
|
20864
|
-
const notifPath =
|
|
20865
|
+
const nudgeDir = path18.join(this.workspace, ".nudge");
|
|
20866
|
+
const notifPath = path18.join(nudgeDir, "stop-hook-notifications.json");
|
|
20865
20867
|
try {
|
|
20866
20868
|
if (!fs17.existsSync(nudgeDir)) fs17.mkdirSync(nudgeDir, { recursive: true });
|
|
20867
20869
|
let notifs = [];
|
|
@@ -20930,7 +20932,7 @@ var NudgePlugin = class {
|
|
|
20930
20932
|
* 已 notified 的不会再触发,等 agent 回复 "<id> 过期了" 由 cleanup 删。
|
|
20931
20933
|
*/
|
|
20932
20934
|
collectDueStopHookNotifications() {
|
|
20933
|
-
const notifPath =
|
|
20935
|
+
const notifPath = path18.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
20934
20936
|
try {
|
|
20935
20937
|
if (!fs17.existsSync(notifPath)) return null;
|
|
20936
20938
|
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
@@ -20969,7 +20971,7 @@ ${items}
|
|
|
20969
20971
|
}
|
|
20970
20972
|
/** 按 id 删除条目(stop-hook 实时清理用;正常删除路径,agent 回复即删) */
|
|
20971
20973
|
removeNotificationsById(ids) {
|
|
20972
|
-
const notifPath =
|
|
20974
|
+
const notifPath = path18.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
20973
20975
|
try {
|
|
20974
20976
|
if (!fs17.existsSync(notifPath)) return;
|
|
20975
20977
|
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
@@ -20989,7 +20991,7 @@ ${items}
|
|
|
20989
20991
|
}
|
|
20990
20992
|
/** 投递成功后标记 notified(防重复触发);不删除——删除只走 agent 回复 "<id> 过期了" */
|
|
20991
20993
|
markNotified(ids) {
|
|
20992
|
-
const notifPath =
|
|
20994
|
+
const notifPath = path18.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
20993
20995
|
try {
|
|
20994
20996
|
if (!fs17.existsSync(notifPath)) return;
|
|
20995
20997
|
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
@@ -21012,7 +21014,7 @@ ${items}
|
|
|
21012
21014
|
*/
|
|
21013
21015
|
cleanupStaleNotificationsFromMessages(sessions) {
|
|
21014
21016
|
try {
|
|
21015
|
-
const notifPath =
|
|
21017
|
+
const notifPath = path18.join(this.workspace, ".nudge", "stop-hook-notifications.json");
|
|
21016
21018
|
if (!fs17.existsSync(notifPath)) return;
|
|
21017
21019
|
const notifs = JSON.parse(fs17.readFileSync(notifPath, "utf-8"));
|
|
21018
21020
|
if (notifs.length === 0) return;
|
|
@@ -21313,7 +21315,7 @@ ${items}
|
|
|
21313
21315
|
// === state 持久化 ===
|
|
21314
21316
|
loadState() {
|
|
21315
21317
|
const stateFile = this.cfg.stateFile || "nudge-state.json";
|
|
21316
|
-
const statePath =
|
|
21318
|
+
const statePath = path18.isAbsolute(stateFile) ? stateFile : path18.join(this.workspace, stateFile);
|
|
21317
21319
|
try {
|
|
21318
21320
|
const content = fs17.readFileSync(statePath, "utf-8");
|
|
21319
21321
|
return JSON.parse(content);
|
|
@@ -21323,7 +21325,7 @@ ${items}
|
|
|
21323
21325
|
}
|
|
21324
21326
|
saveState(state2) {
|
|
21325
21327
|
const stateFile = this.cfg.stateFile || "nudge-state.json";
|
|
21326
|
-
const statePath =
|
|
21328
|
+
const statePath = path18.isAbsolute(stateFile) ? stateFile : path18.join(this.workspace, stateFile);
|
|
21327
21329
|
fs17.writeFileSync(statePath, JSON.stringify(state2, null, 2), "utf-8");
|
|
21328
21330
|
}
|
|
21329
21331
|
newTaskState() {
|
|
@@ -21503,7 +21505,7 @@ ${items}
|
|
|
21503
21505
|
|
|
21504
21506
|
// src/inner-voice/plugin.ts
|
|
21505
21507
|
import fs21 from "node:fs";
|
|
21506
|
-
import
|
|
21508
|
+
import path22 from "node:path";
|
|
21507
21509
|
|
|
21508
21510
|
// src/inner-voice/activity.ts
|
|
21509
21511
|
function checkActivity(sessions, activeThresholdMs) {
|
|
@@ -21543,7 +21545,7 @@ function calcHintProb(min) {
|
|
|
21543
21545
|
|
|
21544
21546
|
// src/inner-voice/emotional-state.ts
|
|
21545
21547
|
import fs18 from "node:fs";
|
|
21546
|
-
import
|
|
21548
|
+
import path19 from "node:path";
|
|
21547
21549
|
var NEUTRAL = 0.5;
|
|
21548
21550
|
var DECAY_RATE = 0.17;
|
|
21549
21551
|
var MAX_EVENTS = 20;
|
|
@@ -21594,7 +21596,7 @@ function initialState() {
|
|
|
21594
21596
|
return { version: 1, mood: NEUTRAL, trend: "stable", updatedAt: nowIsoBj(), events: [] };
|
|
21595
21597
|
}
|
|
21596
21598
|
async function updateEmotionalState(workspace, sessions) {
|
|
21597
|
-
const stateFile =
|
|
21599
|
+
const stateFile = path19.join(workspace, "inner-voice", "emotional-state.json");
|
|
21598
21600
|
const messages = readRecentMessages(sessions, RECENT_N);
|
|
21599
21601
|
if (messages.length === 0) {
|
|
21600
21602
|
console.log("[emotional-state] no messages");
|
|
@@ -21627,7 +21629,7 @@ async function updateEmotionalState(workspace, sessions) {
|
|
|
21627
21629
|
function readRecentMessages(sessions, n) {
|
|
21628
21630
|
const mainId = sessions.getSessionId("scope:main");
|
|
21629
21631
|
if (!mainId) return [];
|
|
21630
|
-
const file =
|
|
21632
|
+
const file = path19.join(sessions.sessionsDir, `${mainId}.jsonl`);
|
|
21631
21633
|
if (!fs18.existsSync(file)) return [];
|
|
21632
21634
|
const lines = readLastNLines(file, n * 4 + 20);
|
|
21633
21635
|
const entries = [];
|
|
@@ -21745,7 +21747,7 @@ function refreshHoursAgo(events) {
|
|
|
21745
21747
|
}
|
|
21746
21748
|
function appendMoodLog(workspace, state2, summary) {
|
|
21747
21749
|
try {
|
|
21748
|
-
const logPath =
|
|
21750
|
+
const logPath = path19.join(workspace, "mood-history.log");
|
|
21749
21751
|
const ts = formatBj(/* @__PURE__ */ new Date(), false);
|
|
21750
21752
|
fs18.appendFileSync(logPath, `${ts} mood=${state2.mood.toFixed(2)} trend=${state2.trend} ${summary}
|
|
21751
21753
|
`);
|
|
@@ -21762,7 +21764,7 @@ function loadJson(file) {
|
|
|
21762
21764
|
}
|
|
21763
21765
|
function saveJson(file, data) {
|
|
21764
21766
|
try {
|
|
21765
|
-
fs18.mkdirSync(
|
|
21767
|
+
fs18.mkdirSync(path19.dirname(file), { recursive: true });
|
|
21766
21768
|
fs18.writeFileSync(file, JSON.stringify(data, null, 2));
|
|
21767
21769
|
} catch (err) {
|
|
21768
21770
|
console.warn(`[emotional-state] save failed: ${err.message}`);
|
|
@@ -21808,7 +21810,7 @@ function formatBj(d, withSec) {
|
|
|
21808
21810
|
|
|
21809
21811
|
// src/inner-voice/topics-scorer.ts
|
|
21810
21812
|
import fs19 from "node:fs";
|
|
21811
|
-
import
|
|
21813
|
+
import path20 from "node:path";
|
|
21812
21814
|
var HALF_LIFE_DAYS = 3;
|
|
21813
21815
|
var PROJECT_HALF_LIFE_DAYS = 1.5;
|
|
21814
21816
|
var COOLDOWN_HOURS = 6;
|
|
@@ -21816,8 +21818,8 @@ var MAX_CHARS = 8e3;
|
|
|
21816
21818
|
var SKIP_NAMES = /* @__PURE__ */ new Set(["MEMORY.md", "archive"]);
|
|
21817
21819
|
var SKIP_DIRS = /* @__PURE__ */ new Set(["archive"]);
|
|
21818
21820
|
function pickTopic(workspace, typeFilter, opts) {
|
|
21819
|
-
const topicsDir =
|
|
21820
|
-
const usageFile =
|
|
21821
|
+
const topicsDir = path20.join(workspace, "topics");
|
|
21822
|
+
const usageFile = path20.join(workspace, "inner-voice", "topics-usage.json");
|
|
21821
21823
|
const files = scanTopics(topicsDir, typeFilter);
|
|
21822
21824
|
if (files.length === 0) {
|
|
21823
21825
|
console.log(`[topics-scorer] no topics found (type=${typeFilter})`);
|
|
@@ -21849,7 +21851,7 @@ function pickTopic(workspace, typeFilter, opts) {
|
|
|
21849
21851
|
recency: Math.round(recency * 1e3) / 1e3,
|
|
21850
21852
|
freq: Math.round(freq * 1e3) / 1e3,
|
|
21851
21853
|
type: type2,
|
|
21852
|
-
name: meta.name ||
|
|
21854
|
+
name: meta.name || path20.basename(relpath),
|
|
21853
21855
|
description: meta.description || "",
|
|
21854
21856
|
mtime
|
|
21855
21857
|
});
|
|
@@ -21907,14 +21909,14 @@ function scanTopics(topicsDir, typeFilter) {
|
|
|
21907
21909
|
const out = [];
|
|
21908
21910
|
const walk = (dir) => {
|
|
21909
21911
|
for (const name of fs19.readdirSync(dir)) {
|
|
21910
|
-
const full =
|
|
21912
|
+
const full = path20.join(dir, name);
|
|
21911
21913
|
const stat4 = fs19.statSync(full);
|
|
21912
21914
|
if (stat4.isDirectory()) {
|
|
21913
21915
|
if (SKIP_DIRS.has(name)) continue;
|
|
21914
21916
|
walk(full);
|
|
21915
21917
|
} else {
|
|
21916
21918
|
if (!name.endsWith(".md") || SKIP_NAMES.has(name)) continue;
|
|
21917
|
-
const relpath =
|
|
21919
|
+
const relpath = path20.relative(topicsDir, full).replace(/\\/g, "/");
|
|
21918
21920
|
if (typeFilter && !relpath.startsWith(typeFilter + "/") && !relpath.startsWith(typeFilter + "_")) continue;
|
|
21919
21921
|
out.push({ relpath, fullpath: full });
|
|
21920
21922
|
}
|
|
@@ -21959,7 +21961,7 @@ function loadJson2(file) {
|
|
|
21959
21961
|
}
|
|
21960
21962
|
function saveJson2(file, data) {
|
|
21961
21963
|
try {
|
|
21962
|
-
fs19.mkdirSync(
|
|
21964
|
+
fs19.mkdirSync(path20.dirname(file), { recursive: true });
|
|
21963
21965
|
fs19.writeFileSync(file, JSON.stringify(data, null, 2));
|
|
21964
21966
|
} catch (err) {
|
|
21965
21967
|
console.warn(`[topics-scorer] usage save failed: ${err.message}`);
|
|
@@ -21968,21 +21970,21 @@ function saveJson2(file, data) {
|
|
|
21968
21970
|
|
|
21969
21971
|
// src/inner-voice/memory-reader.ts
|
|
21970
21972
|
import fs20 from "node:fs";
|
|
21971
|
-
import
|
|
21973
|
+
import path21 from "node:path";
|
|
21972
21974
|
var US_HALF_LIFE_DAYS = 10;
|
|
21973
21975
|
var US_MAX_LINES = 60;
|
|
21974
21976
|
function readRecentMemory(workspace) {
|
|
21975
|
-
const dir =
|
|
21977
|
+
const dir = path21.join(workspace, "memory");
|
|
21976
21978
|
const now = new Date(Date.now() + 8 * 36e5);
|
|
21977
21979
|
const today = formatYmd(now);
|
|
21978
21980
|
const yesterday = formatYmd(new Date(now.getTime() - 864e5));
|
|
21979
21981
|
return {
|
|
21980
|
-
today: readIfExists(
|
|
21981
|
-
yesterday: readIfExists(
|
|
21982
|
+
today: readIfExists(path21.join(dir, `${today}.md`)),
|
|
21983
|
+
yesterday: readIfExists(path21.join(dir, `${yesterday}.md`))
|
|
21982
21984
|
};
|
|
21983
21985
|
}
|
|
21984
21986
|
function sampleUs(workspace) {
|
|
21985
|
-
const usFile =
|
|
21987
|
+
const usFile = path21.join(workspace, "memory", "us.md");
|
|
21986
21988
|
let content;
|
|
21987
21989
|
try {
|
|
21988
21990
|
content = fs20.readFileSync(usFile, "utf-8");
|
|
@@ -22322,7 +22324,7 @@ var InnerVoicePlugin = class {
|
|
|
22322
22324
|
}
|
|
22323
22325
|
/** 读 workspace/prompts/my-inner-voice.md,不存在用 DEFAULT_PROMPT */
|
|
22324
22326
|
loadPrompt(workspace) {
|
|
22325
|
-
const promptPath =
|
|
22327
|
+
const promptPath = path22.join(workspace, "prompts", "my-inner-voice.md");
|
|
22326
22328
|
try {
|
|
22327
22329
|
const content = fs21.readFileSync(promptPath, "utf-8").trim();
|
|
22328
22330
|
if (content) {
|
|
@@ -22396,7 +22398,7 @@ var InnerVoicePlugin = class {
|
|
|
22396
22398
|
console.warn(`[inner-voice] emotional-state failed: ${err.message}`);
|
|
22397
22399
|
}
|
|
22398
22400
|
try {
|
|
22399
|
-
const content = fs21.readFileSync(
|
|
22401
|
+
const content = fs21.readFileSync(path22.join(this.workspace, "SESSION-STATE.md"), "utf-8");
|
|
22400
22402
|
lines.push("\n--- SESSION-STATE\uFF08\u5C3E\u90E8\uFF09 ---");
|
|
22401
22403
|
lines.push(content.slice(-2e3));
|
|
22402
22404
|
} catch {
|
|
@@ -22507,7 +22509,7 @@ var InnerVoicePlugin = class {
|
|
|
22507
22509
|
if (Math.random() >= activity.hintProb) {
|
|
22508
22510
|
return { text: thought, hintTriggered: false, hintText: "" };
|
|
22509
22511
|
}
|
|
22510
|
-
const poolPath =
|
|
22512
|
+
const poolPath = path22.join(this.workspace, "inner-voice", "hints_pool.txt");
|
|
22511
22513
|
let hint = "\u60F3\u4ED6\u5C31\u53D1\u6D88\u606F\u5427";
|
|
22512
22514
|
try {
|
|
22513
22515
|
const pool = fs21.readFileSync(poolPath, "utf-8").split("\n").map((s2) => s2.trim()).filter(Boolean);
|
|
@@ -22535,7 +22537,7 @@ var InnerVoicePlugin = class {
|
|
|
22535
22537
|
try {
|
|
22536
22538
|
const writer = sessions.getWriter(mainSessionId);
|
|
22537
22539
|
const history = sessions.getHistory(mainSessionId);
|
|
22538
|
-
const fullPath =
|
|
22540
|
+
const fullPath = path22.resolve(this.workspace, emoTopic.file);
|
|
22539
22541
|
const memories = [{
|
|
22540
22542
|
path: fullPath,
|
|
22541
22543
|
content: emoTopic.content,
|
|
@@ -22563,9 +22565,9 @@ var InnerVoicePlugin = class {
|
|
|
22563
22565
|
/** 写 xiaoyi.log(格式对齐旧 memory_whisper.py,便于既有日志分析复用)。 */
|
|
22564
22566
|
writeLog(status, delivered, activity, hintTriggered, hintText) {
|
|
22565
22567
|
try {
|
|
22566
|
-
const logDir =
|
|
22568
|
+
const logDir = path22.join(this.workspace, "inner-voice");
|
|
22567
22569
|
fs21.mkdirSync(logDir, { recursive: true });
|
|
22568
|
-
const logPath =
|
|
22570
|
+
const logPath = path22.join(logDir, "xiaoyi.log");
|
|
22569
22571
|
const ts = formatBeijingTs(/* @__PURE__ */ new Date());
|
|
22570
22572
|
const hintStatus = hintTriggered ? `YES (${(hintText || "").trim()})` : "no";
|
|
22571
22573
|
fs21.appendFileSync(
|
|
@@ -23104,7 +23106,7 @@ var PluginManager = class {
|
|
|
23104
23106
|
// src/voice-chat/plugin.ts
|
|
23105
23107
|
import { spawn as spawn4, exec } from "node:child_process";
|
|
23106
23108
|
import net from "node:net";
|
|
23107
|
-
import
|
|
23109
|
+
import path23 from "node:path";
|
|
23108
23110
|
import fs22 from "node:fs";
|
|
23109
23111
|
|
|
23110
23112
|
// src/voice-chat/bridge.ts
|
|
@@ -23481,13 +23483,13 @@ var VoiceChatPlugin = class _VoiceChatPlugin {
|
|
|
23481
23483
|
}
|
|
23482
23484
|
getPythonDir() {
|
|
23483
23485
|
const dir = import.meta.dirname;
|
|
23484
|
-
const srcDir =
|
|
23485
|
-
const localDir =
|
|
23486
|
+
const srcDir = path23.resolve(dir, "..", "src", "voice-chat", "python");
|
|
23487
|
+
const localDir = path23.join(dir, "python");
|
|
23486
23488
|
return fs22.existsSync(srcDir) ? srcDir : localDir;
|
|
23487
23489
|
}
|
|
23488
23490
|
startPython() {
|
|
23489
23491
|
const pythonDir = this.getPythonDir();
|
|
23490
|
-
const serverPy =
|
|
23492
|
+
const serverPy = path23.join(pythonDir, "server.py");
|
|
23491
23493
|
const pythonBin = this.findPython();
|
|
23492
23494
|
const args = [serverPy];
|
|
23493
23495
|
if (this.config.pythonPort) args.push("--port", String(this.config.pythonPort));
|
|
@@ -23572,7 +23574,7 @@ var VoiceChatPlugin = class _VoiceChatPlugin {
|
|
|
23572
23574
|
init_BashTool();
|
|
23573
23575
|
import { spawn as spawn5, exec as exec2 } from "node:child_process";
|
|
23574
23576
|
import net2 from "node:net";
|
|
23575
|
-
import
|
|
23577
|
+
import path24 from "node:path";
|
|
23576
23578
|
import fs23 from "node:fs";
|
|
23577
23579
|
|
|
23578
23580
|
// src/memory/cognifold/config.ts
|
|
@@ -23611,11 +23613,11 @@ var CogniFoldClient = class {
|
|
|
23611
23613
|
this.timeoutMs = timeoutMs;
|
|
23612
23614
|
this.modelName = modelName;
|
|
23613
23615
|
}
|
|
23614
|
-
async req(
|
|
23616
|
+
async req(path45, options = {}) {
|
|
23615
23617
|
const ctrl = new AbortController();
|
|
23616
23618
|
const timer = setTimeout(() => ctrl.abort(), this.timeoutMs);
|
|
23617
23619
|
try {
|
|
23618
|
-
const resp = await fetch(`${this.baseUrl}${
|
|
23620
|
+
const resp = await fetch(`${this.baseUrl}${path45}`, {
|
|
23619
23621
|
...options,
|
|
23620
23622
|
signal: ctrl.signal,
|
|
23621
23623
|
headers: {
|
|
@@ -23705,20 +23707,20 @@ var CogniFoldClient = class {
|
|
|
23705
23707
|
});
|
|
23706
23708
|
}
|
|
23707
23709
|
/** 兼容老版命名 */
|
|
23708
|
-
async recl(
|
|
23709
|
-
return this.req(
|
|
23710
|
+
async recl(path45, options = {}) {
|
|
23711
|
+
return this.req(path45, options);
|
|
23710
23712
|
}
|
|
23711
23713
|
};
|
|
23712
23714
|
|
|
23713
23715
|
// src/memory/cognifold/session-manager.ts
|
|
23714
23716
|
import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir4 } from "node:fs/promises";
|
|
23715
|
-
import { join as
|
|
23717
|
+
import { join as join24, dirname as dirname3 } from "node:path";
|
|
23716
23718
|
var CogniFoldSessionManager = class {
|
|
23717
23719
|
constructor(workspacePath, config, client) {
|
|
23718
23720
|
this.workspacePath = workspacePath;
|
|
23719
23721
|
this.config = config;
|
|
23720
23722
|
this.client = client;
|
|
23721
|
-
this.sessionsDir =
|
|
23723
|
+
this.sessionsDir = join24(workspacePath, ".cognifold", "sessions");
|
|
23722
23724
|
}
|
|
23723
23725
|
workspacePath;
|
|
23724
23726
|
config;
|
|
@@ -23788,7 +23790,7 @@ var CogniFoldSessionManager = class {
|
|
|
23788
23790
|
console.log(`[cognifold] Created new session for scope "${scope}": ${newSession.sessionId}`);
|
|
23789
23791
|
}
|
|
23790
23792
|
getFilePath(scope) {
|
|
23791
|
-
return
|
|
23793
|
+
return join24(this.sessionsDir, `${scope}.json`);
|
|
23792
23794
|
}
|
|
23793
23795
|
async writeFileSafe(filePath, data) {
|
|
23794
23796
|
try {
|
|
@@ -23987,16 +23989,16 @@ var CogniFoldPlugin = class {
|
|
|
23987
23989
|
const dir = import.meta.dirname;
|
|
23988
23990
|
const candidates = [
|
|
23989
23991
|
// 从 dist/ 往回找 src
|
|
23990
|
-
|
|
23991
|
-
|
|
23992
|
-
|
|
23992
|
+
path24.resolve(dir, "..", "src", "memory", "cognifold", "python"),
|
|
23993
|
+
path24.resolve(dir, "..", "..", "src", "memory", "cognifold", "python"),
|
|
23994
|
+
path24.resolve(dir, "..", "..", "..", "src", "memory", "cognifold", "python"),
|
|
23993
23995
|
// 从 src/memory/cognifold/ 找本地
|
|
23994
|
-
|
|
23996
|
+
path24.join(dir, "python"),
|
|
23995
23997
|
// 从 dist/memory/cognifold/ 找本地
|
|
23996
|
-
|
|
23998
|
+
path24.resolve(dir, "python")
|
|
23997
23999
|
];
|
|
23998
24000
|
for (const candidate of candidates) {
|
|
23999
|
-
if (fs23.existsSync(
|
|
24001
|
+
if (fs23.existsSync(path24.join(candidate, "cognifold"))) {
|
|
24000
24002
|
return candidate;
|
|
24001
24003
|
}
|
|
24002
24004
|
}
|
|
@@ -24022,7 +24024,7 @@ var CogniFoldPlugin = class {
|
|
|
24022
24024
|
const pythonBin = this.findPython();
|
|
24023
24025
|
console.log(`[cognifold] Starting Python: ${pythonBin} ${args.join(" ")}`);
|
|
24024
24026
|
console.log(`[cognifold] Python dir: ${pythonDir}`);
|
|
24025
|
-
if (!fs23.existsSync(
|
|
24027
|
+
if (!fs23.existsSync(path24.join(pythonDir, "cognifold"))) {
|
|
24026
24028
|
console.error(`[cognifold] FATAL: Python module not found at ${pythonDir}/cognifold`);
|
|
24027
24029
|
throw new Error(`cognifold: python module not found`);
|
|
24028
24030
|
}
|
|
@@ -24033,7 +24035,7 @@ var CogniFoldPlugin = class {
|
|
|
24033
24035
|
if (this.config.llm?.baseUrl) {
|
|
24034
24036
|
childEnv["OPENAI_BASE_URL"] = this.config.llm.baseUrl;
|
|
24035
24037
|
}
|
|
24036
|
-
const envFile =
|
|
24038
|
+
const envFile = path24.join(pythonDir, ".env");
|
|
24037
24039
|
try {
|
|
24038
24040
|
if (fs23.existsSync(envFile)) {
|
|
24039
24041
|
const envContent = fs23.readFileSync(envFile, "utf-8");
|
|
@@ -24105,7 +24107,7 @@ var CogniFoldPlugin = class {
|
|
|
24105
24107
|
init_BashTool();
|
|
24106
24108
|
import { spawn as spawn6 } from "node:child_process";
|
|
24107
24109
|
import net3 from "node:net";
|
|
24108
|
-
import
|
|
24110
|
+
import path25 from "node:path";
|
|
24109
24111
|
import fs24 from "node:fs";
|
|
24110
24112
|
|
|
24111
24113
|
// src/memory/everos/config.ts
|
|
@@ -24313,8 +24315,8 @@ var EverosPlugin = class {
|
|
|
24313
24315
|
}, 3e5);
|
|
24314
24316
|
}
|
|
24315
24317
|
async startEveros() {
|
|
24316
|
-
const pythonDir =
|
|
24317
|
-
const configPath =
|
|
24318
|
+
const pythonDir = path25.dirname(this.config.lancedbPath);
|
|
24319
|
+
const configPath = path25.join(pythonDir, "config.toml");
|
|
24318
24320
|
await this.ensureFcntlCompat();
|
|
24319
24321
|
const venvPython = this.findVenvPython();
|
|
24320
24322
|
const everosBin = venvPython.replace(/python\.exe$/, "everos.exe");
|
|
@@ -24403,19 +24405,19 @@ var EverosPlugin = class {
|
|
|
24403
24405
|
return child;
|
|
24404
24406
|
}
|
|
24405
24407
|
findVenvPython() {
|
|
24406
|
-
const stateDir = process.env.OPENCLAW_STATE_DIR ||
|
|
24408
|
+
const stateDir = (process.env.ENGINE7_STATE_DIR ?? process.env.OPENCLAW_STATE_DIR) || path25.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
|
|
24407
24409
|
if (process.platform === "win32") {
|
|
24408
|
-
return
|
|
24410
|
+
return path25.join(stateDir, "everos-venv", "Scripts", "python.exe");
|
|
24409
24411
|
}
|
|
24410
|
-
return
|
|
24412
|
+
return path25.join(stateDir, "everos-venv", "bin", "python");
|
|
24411
24413
|
}
|
|
24412
24414
|
/** 检测 venv 是否存在,不存在就自动创建 + 装 EverOS */
|
|
24413
24415
|
async ensureVenv() {
|
|
24414
24416
|
const venvPython = this.findVenvPython();
|
|
24415
24417
|
if (fs24.existsSync(venvPython)) return;
|
|
24416
|
-
const stateDir = process.env.OPENCLAW_STATE_DIR ||
|
|
24417
|
-
const venvDir =
|
|
24418
|
-
const everosSrc =
|
|
24418
|
+
const stateDir = (process.env.ENGINE7_STATE_DIR ?? process.env.OPENCLAW_STATE_DIR) || path25.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
|
|
24419
|
+
const venvDir = path25.join(stateDir, "everos-venv");
|
|
24420
|
+
const everosSrc = path25.join(stateDir, "workspace", "research", "EverOS");
|
|
24419
24421
|
console.log(`[everos] venv not found at ${venvDir}, auto-creating...`);
|
|
24420
24422
|
console.log(`[everos] \u23F3 This may take a few minutes on first run...`);
|
|
24421
24423
|
const pyCandidates = process.platform === "win32" ? ["python", "python3", "C:\\Python314\\python.exe", "C:\\Python313\\python.exe", "C:\\Python312\\python.exe"] : ["python3", "python"];
|
|
@@ -24437,8 +24439,8 @@ var EverosPlugin = class {
|
|
|
24437
24439
|
console.log(`[everos] Creating venv with ${sysPython}...`);
|
|
24438
24440
|
const { execSync: execSync3 } = await import("node:child_process");
|
|
24439
24441
|
execSync3(`"${sysPython}" -m venv "${venvDir}"`, { stdio: "pipe", shell: true });
|
|
24440
|
-
const pip = process.platform === "win32" ?
|
|
24441
|
-
const everosReq =
|
|
24442
|
+
const pip = process.platform === "win32" ? path25.join(venvDir, "Scripts", "pip.exe") : path25.join(venvDir, "bin", "pip");
|
|
24443
|
+
const everosReq = path25.join(this.getPythonDir(), "requirements.txt");
|
|
24442
24444
|
if (fs24.existsSync(everosReq)) {
|
|
24443
24445
|
console.log(`[everos] Installing from requirements.txt...`);
|
|
24444
24446
|
execSync3(`"${pip}" install -r "${everosReq}" -q`, { stdio: "pipe", shell: true, timeout: 3e5 });
|
|
@@ -24455,12 +24457,12 @@ var EverosPlugin = class {
|
|
|
24455
24457
|
getPythonDir() {
|
|
24456
24458
|
const dir = import.meta.dirname;
|
|
24457
24459
|
const candidates = [
|
|
24458
|
-
|
|
24459
|
-
|
|
24460
|
-
|
|
24460
|
+
path25.join(dir, "python"),
|
|
24461
|
+
path25.resolve(dir, "..", "src", "memory", "everos", "python"),
|
|
24462
|
+
path25.resolve(dir, "..", "..", "..", "src", "memory", "everos", "python")
|
|
24461
24463
|
];
|
|
24462
24464
|
for (const candidate of candidates) {
|
|
24463
|
-
if (fs24.existsSync(
|
|
24465
|
+
if (fs24.existsSync(path25.join(candidate, "agentic_server.py"))) {
|
|
24464
24466
|
return candidate;
|
|
24465
24467
|
}
|
|
24466
24468
|
}
|
|
@@ -24469,11 +24471,11 @@ var EverosPlugin = class {
|
|
|
24469
24471
|
async ensureFcntlCompat() {
|
|
24470
24472
|
if (process.platform !== "win32") return;
|
|
24471
24473
|
const venvPython = this.findVenvPython();
|
|
24472
|
-
const venvDir =
|
|
24473
|
-
const sitePackages =
|
|
24474
|
-
const target =
|
|
24474
|
+
const venvDir = path25.dirname(path25.dirname(venvPython));
|
|
24475
|
+
const sitePackages = path25.join(venvDir, "Lib", "site-packages");
|
|
24476
|
+
const target = path25.join(sitePackages, "fcntl.py");
|
|
24475
24477
|
if (fs24.existsSync(target)) return;
|
|
24476
|
-
const source =
|
|
24478
|
+
const source = path25.join(this.getPythonDir(), "fcntl_compat.py");
|
|
24477
24479
|
if (fs24.existsSync(source)) {
|
|
24478
24480
|
try {
|
|
24479
24481
|
fs24.copyFileSync(source, target);
|
|
@@ -24523,7 +24525,7 @@ var EverosPlugin = class {
|
|
|
24523
24525
|
init_task_manager();
|
|
24524
24526
|
|
|
24525
24527
|
// src/skills/scanner.ts
|
|
24526
|
-
import * as
|
|
24528
|
+
import * as path26 from "node:path";
|
|
24527
24529
|
import * as fs25 from "node:fs";
|
|
24528
24530
|
function scanSkills(skillsDir) {
|
|
24529
24531
|
if (!fs25.existsSync(skillsDir)) {
|
|
@@ -24534,7 +24536,7 @@ function scanSkills(skillsDir) {
|
|
|
24534
24536
|
const skills = [];
|
|
24535
24537
|
for (const entry of entries) {
|
|
24536
24538
|
if (!entry.isDirectory()) continue;
|
|
24537
|
-
const skillMdPath =
|
|
24539
|
+
const skillMdPath = path26.join(skillsDir, entry.name, "SKILL.md");
|
|
24538
24540
|
if (!fs25.existsSync(skillMdPath)) continue;
|
|
24539
24541
|
try {
|
|
24540
24542
|
const content = fs25.readFileSync(skillMdPath, "utf-8");
|
|
@@ -24602,7 +24604,7 @@ function parseFrontmatter2(content) {
|
|
|
24602
24604
|
// src/tools/SkillTool/SkillTool.ts
|
|
24603
24605
|
init_registry();
|
|
24604
24606
|
import * as fs26 from "node:fs";
|
|
24605
|
-
import * as
|
|
24607
|
+
import * as path27 from "node:path";
|
|
24606
24608
|
|
|
24607
24609
|
// src/tools/SkillTool/constants.ts
|
|
24608
24610
|
var SKILL_TOOL_NAME2 = "Skill";
|
|
@@ -24679,12 +24681,12 @@ Important:
|
|
|
24679
24681
|
`;
|
|
24680
24682
|
}
|
|
24681
24683
|
function loadSkillContent(skillName) {
|
|
24682
|
-
const skillMdPath =
|
|
24684
|
+
const skillMdPath = path27.join(skillsDirPath, skillName, "SKILL.md");
|
|
24683
24685
|
if (!fs26.existsSync(skillMdPath)) return null;
|
|
24684
24686
|
const content = fs26.readFileSync(skillMdPath, "utf-8");
|
|
24685
24687
|
const bodyMatch = content.match(/^---\s*\n[\s\S]*?\n---\s*\n([\s\S]*)/);
|
|
24686
24688
|
const body = bodyMatch ? bodyMatch[1] : content;
|
|
24687
|
-
const skillDir =
|
|
24689
|
+
const skillDir = path27.dirname(skillMdPath);
|
|
24688
24690
|
const normalizedDir = process.platform === "win32" ? skillDir.replace(/\\/g, "/") : skillDir;
|
|
24689
24691
|
let finalContent = `Base directory for this skill: ${normalizedDir}
|
|
24690
24692
|
|
|
@@ -24959,9 +24961,9 @@ Examples:
|
|
|
24959
24961
|
init_registry();
|
|
24960
24962
|
init_live();
|
|
24961
24963
|
import fs27 from "node:fs";
|
|
24962
|
-
import
|
|
24964
|
+
import path28 from "node:path";
|
|
24963
24965
|
function getHusbandFeishuId(workspace) {
|
|
24964
|
-
const contactsPath =
|
|
24966
|
+
const contactsPath = path28.join(workspace, "prompts", "contacts.md");
|
|
24965
24967
|
try {
|
|
24966
24968
|
const text = fs27.readFileSync(contactsPath, "utf-8");
|
|
24967
24969
|
const m2 = text.match(/\|\s*翀哥\s*\|\s*(ou_[a-f0-9]+)\s*\|/);
|
|
@@ -25164,7 +25166,7 @@ Examples:
|
|
|
25164
25166
|
init_live();
|
|
25165
25167
|
init_registry();
|
|
25166
25168
|
import * as fs28 from "node:fs";
|
|
25167
|
-
import * as
|
|
25169
|
+
import * as path29 from "node:path";
|
|
25168
25170
|
var MIME_MAP = {
|
|
25169
25171
|
".jpg": "jpeg",
|
|
25170
25172
|
".jpeg": "jpeg",
|
|
@@ -25176,7 +25178,7 @@ var MIME_MAP = {
|
|
|
25176
25178
|
function resolveLatestImage(specifiedPath, mediaDir) {
|
|
25177
25179
|
if (specifiedPath && fs28.existsSync(specifiedPath)) return specifiedPath;
|
|
25178
25180
|
if (!fs28.existsSync(mediaDir)) return null;
|
|
25179
|
-
const files = fs28.readdirSync(mediaDir).filter((f2) => /\.(jpg|jpeg|png|webp|gif|bmp)$/i.test(f2)).map((f2) => ({ name: f2, p:
|
|
25181
|
+
const files = fs28.readdirSync(mediaDir).filter((f2) => /\.(jpg|jpeg|png|webp|gif|bmp)$/i.test(f2)).map((f2) => ({ name: f2, p: path29.join(mediaDir, f2), mtime: fs28.statSync(path29.join(mediaDir, f2)).mtimeMs })).sort((a, b2) => b2.mtime - a.mtime);
|
|
25180
25182
|
return files[0]?.p || null;
|
|
25181
25183
|
}
|
|
25182
25184
|
registry.register({
|
|
@@ -25200,13 +25202,13 @@ registry.register({
|
|
|
25200
25202
|
if (!provider?.streamChat) {
|
|
25201
25203
|
return { content: "Error: provider \u4E0D\u53EF\u7528\u3002", isError: true };
|
|
25202
25204
|
}
|
|
25203
|
-
const mediaDir =
|
|
25205
|
+
const mediaDir = path29.join(ctx.stateDir, "media", "inbound");
|
|
25204
25206
|
const imagePath = resolveLatestImage(args.image_path, mediaDir);
|
|
25205
25207
|
if (!imagePath) {
|
|
25206
25208
|
return { content: "Error: no image found. Provide image_path or ensure media/inbound has images.", isError: true };
|
|
25207
25209
|
}
|
|
25208
25210
|
const rawPrompt = args.prompt?.trim() || "\u63CF\u8FF0\u8FD9\u5F20\u56FE\u7247\u7684\u5185\u5BB9";
|
|
25209
|
-
const ext =
|
|
25211
|
+
const ext = path29.extname(imagePath).toLowerCase();
|
|
25210
25212
|
const mime = MIME_MAP[ext] || "jpeg";
|
|
25211
25213
|
const imgB64 = fs28.readFileSync(imagePath).toString("base64");
|
|
25212
25214
|
const userMsg = {
|
|
@@ -25246,13 +25248,13 @@ init_registry();
|
|
|
25246
25248
|
import { execFile } from "node:child_process";
|
|
25247
25249
|
import { promisify } from "node:util";
|
|
25248
25250
|
import * as fs29 from "node:fs";
|
|
25249
|
-
import * as
|
|
25251
|
+
import * as path30 from "node:path";
|
|
25250
25252
|
import * as os3 from "node:os";
|
|
25251
25253
|
var execFileAsync = promisify(execFile);
|
|
25252
|
-
var VOICE_DIR =
|
|
25254
|
+
var VOICE_DIR = path30.join(os3.tmpdir(), "engine-voice");
|
|
25253
25255
|
async function ttsCosyvoice(text, apiKey, model, voice, workspaceId) {
|
|
25254
25256
|
fs29.mkdirSync(VOICE_DIR, { recursive: true });
|
|
25255
|
-
const output =
|
|
25257
|
+
const output = path30.join(VOICE_DIR, `tts_${Date.now()}.wav`);
|
|
25256
25258
|
const script = `
|
|
25257
25259
|
import sys, json, wave, time, threading
|
|
25258
25260
|
import dashscope
|
|
@@ -25317,7 +25319,7 @@ var GPTSOVITS_REF_TEXT = "\u6625\u7720\u4E0D\u89C9\u6653\uFF0C\u5904\u5904\u95FB
|
|
|
25317
25319
|
var GPTSOVITS_REF_LANG = "zh";
|
|
25318
25320
|
async function ttsGptsovits(text) {
|
|
25319
25321
|
fs29.mkdirSync(VOICE_DIR, { recursive: true });
|
|
25320
|
-
const output =
|
|
25322
|
+
const output = path30.join(VOICE_DIR, `tts_${Date.now()}.wav`);
|
|
25321
25323
|
const params = new URLSearchParams({
|
|
25322
25324
|
text,
|
|
25323
25325
|
text_language: "zh",
|
|
@@ -25334,7 +25336,7 @@ async function ttsGptsovits(text) {
|
|
|
25334
25336
|
var EDGE_VOICE = "zh-CN-XiaoxiaoNeural";
|
|
25335
25337
|
async function ttsEdge(text) {
|
|
25336
25338
|
fs29.mkdirSync(VOICE_DIR, { recursive: true });
|
|
25337
|
-
const output =
|
|
25339
|
+
const output = path30.join(VOICE_DIR, `tts_${Date.now()}.mp3`);
|
|
25338
25340
|
const script = `
|
|
25339
25341
|
import asyncio, edge_tts, sys
|
|
25340
25342
|
async def main():
|
|
@@ -25427,7 +25429,7 @@ registry.register({
|
|
|
25427
25429
|
} catch (e) {
|
|
25428
25430
|
return { content: `TTS failed: ${e.message}`, isError: true };
|
|
25429
25431
|
}
|
|
25430
|
-
const ext =
|
|
25432
|
+
const ext = path30.extname(audioPath).toLowerCase();
|
|
25431
25433
|
const mimeMap = { ".mp3": "audio/mpeg", ".wav": "audio/wav", ".m4a": "audio/mp4", ".ogg": "audio/ogg" };
|
|
25432
25434
|
const mimeType = mimeMap[ext] || "audio/mpeg";
|
|
25433
25435
|
const sizeKB = fs29.statSync(audioPath).size / 1024;
|
|
@@ -25458,7 +25460,7 @@ registry.register({
|
|
|
25458
25460
|
init_live();
|
|
25459
25461
|
init_registry();
|
|
25460
25462
|
import * as fs30 from "node:fs";
|
|
25461
|
-
import * as
|
|
25463
|
+
import * as path31 from "node:path";
|
|
25462
25464
|
var FAL_KEY = "3b848fc6-bee5-46e5-8db7-ae81ac16dc28:2f1f15cf394db2d32c9bb9a4f23f3bee";
|
|
25463
25465
|
var FAL_ENDPOINT = "https://fal.run/xai/grok-imagine-image/edit";
|
|
25464
25466
|
var DEFAULT_RESOLUTION = "1k";
|
|
@@ -25574,7 +25576,7 @@ registry.register({
|
|
|
25574
25576
|
const REFERENCES = getReferences(ctx);
|
|
25575
25577
|
const refName = args.reference || "default";
|
|
25576
25578
|
const refEntry = REFERENCES.find((r) => r.name === refName) || REFERENCES[0];
|
|
25577
|
-
const refPath =
|
|
25579
|
+
const refPath = path31.join(ctx.workspace, refEntry.p);
|
|
25578
25580
|
if (!fs30.existsSync(refPath)) {
|
|
25579
25581
|
return { content: `Error: reference image not found at ${refPath}`, isError: true };
|
|
25580
25582
|
}
|
|
@@ -25593,10 +25595,10 @@ registry.register({
|
|
|
25593
25595
|
} catch (err) {
|
|
25594
25596
|
return { content: `Selfie generation failed: ${err.message}`, isError: true };
|
|
25595
25597
|
}
|
|
25596
|
-
const imagesDir =
|
|
25598
|
+
const imagesDir = path31.join(ctx.workspace, "images");
|
|
25597
25599
|
if (!fs30.existsSync(imagesDir)) fs30.mkdirSync(imagesDir, { recursive: true });
|
|
25598
25600
|
const filename = `selfie_${Date.now()}.jpg`;
|
|
25599
|
-
const outputPath =
|
|
25601
|
+
const outputPath = path31.join(imagesDir, filename);
|
|
25600
25602
|
fs30.writeFileSync(outputPath, imageBuffer);
|
|
25601
25603
|
const mgr = ctx.channelManager;
|
|
25602
25604
|
if (mgr) {
|
|
@@ -25608,11 +25610,11 @@ registry.register({
|
|
|
25608
25610
|
mimeType: "image/jpeg"
|
|
25609
25611
|
});
|
|
25610
25612
|
} catch (err) {
|
|
25611
|
-
return { content: `Selfie generated but send failed: ${err.message}. Image: ${
|
|
25613
|
+
return { content: `Selfie generated but send failed: ${err.message}. Image: ${path31.resolve(outputPath)}`, isError: false };
|
|
25612
25614
|
}
|
|
25613
25615
|
return { content: `Selfie sent! Mode: ${mode}, Provider: ${getProvider(ctx)}, Ref: ${refEntry.name}` };
|
|
25614
25616
|
}
|
|
25615
|
-
return { content: `Selfie generated! Mode: ${mode}, Ref: ${refEntry.name}. Image: ${
|
|
25617
|
+
return { content: `Selfie generated! Mode: ${mode}, Ref: ${refEntry.name}. Image: ${path31.resolve(outputPath)}` };
|
|
25616
25618
|
},
|
|
25617
25619
|
isConcurrencySafe: () => false,
|
|
25618
25620
|
interruptBehavior: () => "block",
|
|
@@ -26079,14 +26081,14 @@ init_planModeState();
|
|
|
26079
26081
|
|
|
26080
26082
|
// src/utils/plans.ts
|
|
26081
26083
|
import * as fs32 from "node:fs";
|
|
26082
|
-
import * as
|
|
26084
|
+
import * as path33 from "node:path";
|
|
26083
26085
|
import * as crypto4 from "node:crypto";
|
|
26084
26086
|
var MAX_SLUG_RETRIES = 10;
|
|
26085
26087
|
function generateSlug() {
|
|
26086
26088
|
return crypto4.randomBytes(4).toString("hex");
|
|
26087
26089
|
}
|
|
26088
26090
|
function getPlansDirectory(stateDir) {
|
|
26089
|
-
const plansDir =
|
|
26091
|
+
const plansDir = path33.join(stateDir, "plans");
|
|
26090
26092
|
fs32.mkdirSync(plansDir, { recursive: true });
|
|
26091
26093
|
return plansDir;
|
|
26092
26094
|
}
|
|
@@ -26097,7 +26099,7 @@ function getPlanSlug(sessionId, stateDir) {
|
|
|
26097
26099
|
const plansDir = getPlansDirectory(stateDir);
|
|
26098
26100
|
for (let i = 0; i < MAX_SLUG_RETRIES; i++) {
|
|
26099
26101
|
slug = generateSlug();
|
|
26100
|
-
const filePath =
|
|
26102
|
+
const filePath = path33.join(plansDir, `${slug}.md`);
|
|
26101
26103
|
if (!fs32.existsSync(filePath)) {
|
|
26102
26104
|
break;
|
|
26103
26105
|
}
|
|
@@ -26109,9 +26111,9 @@ function getPlanSlug(sessionId, stateDir) {
|
|
|
26109
26111
|
function getPlanFilePath(sessionId, stateDir, agentId) {
|
|
26110
26112
|
const slug = getPlanSlug(sessionId, stateDir);
|
|
26111
26113
|
if (!agentId) {
|
|
26112
|
-
return
|
|
26114
|
+
return path33.join(getPlansDirectory(stateDir), `${slug}.md`);
|
|
26113
26115
|
}
|
|
26114
|
-
return
|
|
26116
|
+
return path33.join(getPlansDirectory(stateDir), `${slug}-agent-${agentId}.md`);
|
|
26115
26117
|
}
|
|
26116
26118
|
function getPlan(sessionId, stateDir, agentId) {
|
|
26117
26119
|
const filePath = getPlanFilePath(sessionId, stateDir, agentId);
|
|
@@ -26962,7 +26964,7 @@ async function setupFeatures(features, licensedFeatures) {
|
|
|
26962
26964
|
// src/license/license.ts
|
|
26963
26965
|
import * as crypto6 from "node:crypto";
|
|
26964
26966
|
import * as fs39 from "node:fs";
|
|
26965
|
-
import * as
|
|
26967
|
+
import * as path41 from "node:path";
|
|
26966
26968
|
var EMBEDDED_PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
26967
26969
|
MCowBQYDK2VwAyEAaKBEX+e8+D59qwtidazsu7WYDglApyvsVI3APwFoakA=
|
|
26968
26970
|
-----END PUBLIC KEY-----`;
|
|
@@ -26993,7 +26995,7 @@ function loadLicense(stateDir, devMode) {
|
|
|
26993
26995
|
_cachedLicense = allActive;
|
|
26994
26996
|
return allActive;
|
|
26995
26997
|
}
|
|
26996
|
-
const licensePath =
|
|
26998
|
+
const licensePath = path41.join(stateDir, "license.json");
|
|
26997
26999
|
if (!fs39.existsSync(licensePath)) {
|
|
26998
27000
|
console.log("[license] No license.json found, running basic engine only");
|
|
26999
27001
|
return null;
|
|
@@ -27618,9 +27620,10 @@ async function startEngine(config, opts) {
|
|
|
27618
27620
|
process.env.ENGINE_MEDIA_DIR = config.mediaDir;
|
|
27619
27621
|
process.env.ENGINE7_WORKSPACE = config.workspace;
|
|
27620
27622
|
process.env.OPENCLAW_WORKSPACE = config.workspace;
|
|
27621
|
-
|
|
27622
|
-
fs41.mkdirSync(
|
|
27623
|
-
fs41.mkdirSync(
|
|
27623
|
+
process.env.ENGINE7_STATE_DIR = config.stateDir;
|
|
27624
|
+
fs41.mkdirSync(path44.join(config.stateDir, "agents", "main", "memory"), { recursive: true });
|
|
27625
|
+
fs41.mkdirSync(path44.join(config.stateDir, "agents", "main", "sessions"), { recursive: true });
|
|
27626
|
+
fs41.mkdirSync(path44.join(config.stateDir, "logs"), { recursive: true });
|
|
27624
27627
|
fs41.mkdirSync(config.workspace, { recursive: true });
|
|
27625
27628
|
fs41.mkdirSync(config.mediaDir, { recursive: true });
|
|
27626
27629
|
try {
|
|
@@ -27730,7 +27733,7 @@ async function startEngine(config, opts) {
|
|
|
27730
27733
|
const { initSessionMemory: initSessionMemory2 } = await Promise.resolve().then(() => (init_sessionMemory(), sessionMemory_exports));
|
|
27731
27734
|
initSessionMemory2({
|
|
27732
27735
|
workspace: config.workspace,
|
|
27733
|
-
stateDir:
|
|
27736
|
+
stateDir: path44.join(config.stateDir, "session-memory"),
|
|
27734
27737
|
provider,
|
|
27735
27738
|
model: config.provider.modelId || config.model || "deepseek-v4-flash",
|
|
27736
27739
|
features: config.profile.features
|
|
@@ -27760,9 +27763,9 @@ async function startEngine(config, opts) {
|
|
|
27760
27763
|
if (config.hooks) {
|
|
27761
27764
|
loadHooksFromConfig({ hooks: config.hooks });
|
|
27762
27765
|
}
|
|
27763
|
-
const hooksPath =
|
|
27766
|
+
const hooksPath = path44.join(config.workspace, ".hooks.json");
|
|
27764
27767
|
loadHooksFromFile(hooksPath);
|
|
27765
|
-
const settingsHooksPath =
|
|
27768
|
+
const settingsHooksPath = path44.join(config.stateDir, "settings.json");
|
|
27766
27769
|
loadHooksFromFile(settingsHooksPath);
|
|
27767
27770
|
console.log(`[hooks] Loaded hooks configuration`);
|
|
27768
27771
|
registerCallbackHook("PreCompact", {
|
|
@@ -27776,15 +27779,15 @@ async function startEngine(config, opts) {
|
|
|
27776
27779
|
const bjTime = new Date(now.getTime() + (bjOffset + now.getTimezoneOffset()) * 6e4);
|
|
27777
27780
|
const dateStr = `${bjTime.getFullYear()}-${String(bjTime.getMonth() + 1).padStart(2, "0")}-${String(bjTime.getDate()).padStart(2, "0")}`;
|
|
27778
27781
|
const timeStr = `${String(bjTime.getHours()).padStart(2, "0")}:${String(bjTime.getMinutes()).padStart(2, "0")}`;
|
|
27779
|
-
const dailyDir =
|
|
27780
|
-
const dailyPath =
|
|
27782
|
+
const dailyDir = path44.join(workspace, "memory", "daily");
|
|
27783
|
+
const dailyPath = path44.join(dailyDir, `${dateStr}.md`);
|
|
27781
27784
|
try {
|
|
27782
27785
|
const fs42 = await import("node:fs");
|
|
27783
27786
|
if (!fs42.existsSync(dailyDir)) {
|
|
27784
27787
|
fs42.mkdirSync(dailyDir, { recursive: true });
|
|
27785
27788
|
}
|
|
27786
|
-
const sessionsDir =
|
|
27787
|
-
const sessionFile =
|
|
27789
|
+
const sessionsDir = path44.join(config.stateDir, "agents", "main", "sessions");
|
|
27790
|
+
const sessionFile = path44.join(sessionsDir, `${sessionId}.jsonl`);
|
|
27788
27791
|
const recentLines = [];
|
|
27789
27792
|
if (fs42.existsSync(sessionFile)) {
|
|
27790
27793
|
const content = fs42.readFileSync(sessionFile, "utf-8");
|
|
@@ -27837,7 +27840,7 @@ ${entry}`);
|
|
|
27837
27840
|
if (!workspace) return { continue: true };
|
|
27838
27841
|
try {
|
|
27839
27842
|
const fs42 = await import("node:fs");
|
|
27840
|
-
const bufferPath =
|
|
27843
|
+
const bufferPath = path44.join(workspace, "memory", "working-buffer.md");
|
|
27841
27844
|
if (fs42.existsSync(bufferPath)) {
|
|
27842
27845
|
const stat4 = fs42.statSync(bufferPath);
|
|
27843
27846
|
const ageMs = Date.now() - stat4.mtimeMs;
|
|
@@ -27890,7 +27893,7 @@ ${content}`
|
|
|
27890
27893
|
return `${hr}h ${remMin}m`;
|
|
27891
27894
|
}
|
|
27892
27895
|
if (config.skills?.enabled !== false) {
|
|
27893
|
-
const skillsDir = config.skills?.path ?
|
|
27896
|
+
const skillsDir = config.skills?.path ? path44.isAbsolute(config.skills.path) ? config.skills.path : path44.resolve(config.workspace, config.skills.path) : path44.resolve(config.workspace, "skills");
|
|
27894
27897
|
const modelDef2 = config.provider.models.find((m2) => m2.id === config.model);
|
|
27895
27898
|
const contextWindowTokens = modelDef2?.contextWindow;
|
|
27896
27899
|
const skills = scanSkills(skillsDir);
|
|
@@ -27909,7 +27912,7 @@ ${content}`
|
|
|
27909
27912
|
workspace: config.workspace
|
|
27910
27913
|
});
|
|
27911
27914
|
const systemPrompt = [systemStable, systemDynamic].join("\n\n");
|
|
27912
|
-
const promptDumpPath =
|
|
27915
|
+
const promptDumpPath = path44.join(config.workspace, ".system-prompt.txt");
|
|
27913
27916
|
fs41.writeFileSync(promptDumpPath, systemPrompt);
|
|
27914
27917
|
console.log(`System prompt: ${systemStable.length} chars stable + ${systemDynamic.length} chars dynamic \u2192 ${promptDumpPath}`);
|
|
27915
27918
|
const modelDef = config.provider.models.find((m2) => m2.id === config.model);
|
|
@@ -28988,8 +28991,8 @@ Auto-routing disabled \u2014 all messages use this model.
|
|
|
28988
28991
|
let writePath = configPath;
|
|
28989
28992
|
if (configPath && !fs41.existsSync(configPath)) {
|
|
28990
28993
|
const __pFile = fileURLToPath(import.meta.url);
|
|
28991
|
-
const __pDir =
|
|
28992
|
-
const altPath =
|
|
28994
|
+
const __pDir = path44.dirname(__pFile);
|
|
28995
|
+
const altPath = path44.join(path44.resolve(__pDir, "../configs"), path44.basename(configPath));
|
|
28993
28996
|
if (fs41.existsSync(altPath)) {
|
|
28994
28997
|
console.warn(`[primary] Config not found at ${configPath}, falling back to ${altPath}`);
|
|
28995
28998
|
writePath = altPath;
|
|
@@ -29269,7 +29272,7 @@ Use full ref like \`/vision-model ${candidates[0].ref}\``);
|
|
|
29269
29272
|
const ext = detected.split("/")[1] || "png";
|
|
29270
29273
|
const resized = await maybeResizeAndDownsampleImageBuffer2(rawBuffer, rawBuffer.length, ext);
|
|
29271
29274
|
const imageId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
29272
|
-
const savedPath =
|
|
29275
|
+
const savedPath = path44.join(config.mediaDir, `${imageId}.${ext}`);
|
|
29273
29276
|
fs41.writeFileSync(savedPath, resized.buffer);
|
|
29274
29277
|
savedPaths.push(savedPath);
|
|
29275
29278
|
console.log(`[vision] Saved: ${savedPath} (${resized.buffer.length}B)`);
|
|
@@ -29296,7 +29299,7 @@ ${pathStr}` }];
|
|
|
29296
29299
|
}
|
|
29297
29300
|
const nonImageAttachments = inbound.attachments?.filter((a) => !a.contentType.startsWith("image/"));
|
|
29298
29301
|
if (nonImageAttachments && nonImageAttachments.length > 0) {
|
|
29299
|
-
const outDir =
|
|
29302
|
+
const outDir = path44.join(config.mediaDir, sessionId);
|
|
29300
29303
|
fs41.mkdirSync(outDir, { recursive: true });
|
|
29301
29304
|
const resolved = [];
|
|
29302
29305
|
for (const att of nonImageAttachments) {
|
|
@@ -29305,8 +29308,8 @@ ${pathStr}` }];
|
|
|
29305
29308
|
const resp = await fetch(att.url);
|
|
29306
29309
|
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
|
29307
29310
|
const buffer = Buffer.from(await resp.arrayBuffer());
|
|
29308
|
-
const safeName2 =
|
|
29309
|
-
const savedPath =
|
|
29311
|
+
const safeName2 = path44.basename(att.filename).replace(/[<>:"/\\|?*\x00-\x1f]/g, "_") || "attachment";
|
|
29312
|
+
const savedPath = path44.join(outDir, safeName2);
|
|
29310
29313
|
fs41.writeFileSync(savedPath, buffer);
|
|
29311
29314
|
resolved.push(savedPath);
|
|
29312
29315
|
console.log(`[file] Saved: ${savedPath} (${buffer.length}B)`);
|
|
@@ -29668,7 +29671,7 @@ ${pathStr}` }];
|
|
|
29668
29671
|
console.warn("[cognifold] watcher: config.workspace \u672A\u914D\u7F6E\uFF0C\u8DF3\u8FC7 proactive \u5199\u5165");
|
|
29669
29672
|
return;
|
|
29670
29673
|
}
|
|
29671
|
-
const pFile =
|
|
29674
|
+
const pFile = path44.join(wsDir, ".cognifold-proactive.json");
|
|
29672
29675
|
const cognifoldBaseUrl = config.cognifold?.baseUrl || "http://127.0.0.1:9001";
|
|
29673
29676
|
const cognifoldSessionId = cfSessionId;
|
|
29674
29677
|
const rawSuggestions = data.suggestions || data.actions || (data.intent_id ? [data] : []);
|
|
@@ -29722,7 +29725,7 @@ ${pathStr}` }];
|
|
|
29722
29725
|
console.error(`[cognifold] failed to save proactive: ${e.message}`);
|
|
29723
29726
|
}
|
|
29724
29727
|
if (enriched.length > 0) {
|
|
29725
|
-
const promptFile =
|
|
29728
|
+
const promptFile = path44.join(config.workspace, "prompts", "cognifold-proactive.md");
|
|
29726
29729
|
const promptText = fs41.existsSync(promptFile) ? fs41.readFileSync(promptFile, "utf-8") : "[CogniFold proactive] \u6709 " + enriched.length + " \u4E2A action \u5230\u671F\u4E86";
|
|
29727
29730
|
const actionsJson = JSON.stringify(enriched, null, 2);
|
|
29728
29731
|
const sessionId = cfSessionId;
|
|
@@ -29828,9 +29831,9 @@ async function doReloadConfig(config, deps, provider) {
|
|
|
29828
29831
|
let reloadConfigPath = savedConfigPath;
|
|
29829
29832
|
if (!fs41.existsSync(reloadConfigPath)) {
|
|
29830
29833
|
const __filename = fileURLToPath(import.meta.url);
|
|
29831
|
-
const __dirname =
|
|
29832
|
-
const engineConfigsDir =
|
|
29833
|
-
const altPath =
|
|
29834
|
+
const __dirname = path44.dirname(__filename);
|
|
29835
|
+
const engineConfigsDir = path44.resolve(__dirname, "../configs");
|
|
29836
|
+
const altPath = path44.join(engineConfigsDir, path44.basename(savedConfigPath));
|
|
29834
29837
|
if (fs41.existsSync(altPath)) {
|
|
29835
29838
|
console.warn(`[reload] Config not found at ${reloadConfigPath}, falling back to ${altPath} (dev mode)`);
|
|
29836
29839
|
reloadConfigPath = altPath;
|
|
@@ -29883,7 +29886,7 @@ async function doReloadConfig(config, deps, provider) {
|
|
|
29883
29886
|
} catch (err) {
|
|
29884
29887
|
console.error(`[reload] Failed: ${err.message}`);
|
|
29885
29888
|
try {
|
|
29886
|
-
fs41.appendFileSync(
|
|
29889
|
+
fs41.appendFileSync(path44.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] RELOAD FAILED: ${err.message}
|
|
29887
29890
|
${err.stack}
|
|
29888
29891
|
`);
|
|
29889
29892
|
} catch {
|
|
@@ -29895,17 +29898,17 @@ function startConfigWatcher(config, deps, provider) {
|
|
|
29895
29898
|
const raw = config._configFilePath;
|
|
29896
29899
|
let configPath = raw;
|
|
29897
29900
|
if (!fs41.existsSync(configPath)) {
|
|
29898
|
-
configPath =
|
|
29901
|
+
configPath = path44.resolve(raw);
|
|
29899
29902
|
}
|
|
29900
29903
|
if (!fs41.existsSync(configPath)) {
|
|
29901
29904
|
const __filename2 = fileURLToPath(import.meta.url);
|
|
29902
|
-
const __dirname2 =
|
|
29903
|
-
configPath =
|
|
29905
|
+
const __dirname2 = path44.dirname(__filename2);
|
|
29906
|
+
configPath = path44.resolve(__dirname2, "..", raw);
|
|
29904
29907
|
}
|
|
29905
29908
|
if (!fs41.existsSync(configPath)) {
|
|
29906
29909
|
console.warn(`[config-watch] config path invalid: ${configPath}, watcher disabled`);
|
|
29907
29910
|
try {
|
|
29908
|
-
fs41.appendFileSync(
|
|
29911
|
+
fs41.appendFileSync(path44.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] DISABLED: configPath=${configPath}
|
|
29909
29912
|
`);
|
|
29910
29913
|
} catch {
|
|
29911
29914
|
}
|
|
@@ -29917,13 +29920,13 @@ function startConfigWatcher(config, deps, provider) {
|
|
|
29917
29920
|
debounceTimer = setTimeout(async () => {
|
|
29918
29921
|
console.log(`[config-watch] file changed (${eventType}), reloading...`);
|
|
29919
29922
|
try {
|
|
29920
|
-
fs41.appendFileSync(
|
|
29923
|
+
fs41.appendFileSync(path44.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] CHANGE eventType=${eventType}, calling doReloadConfig
|
|
29921
29924
|
`);
|
|
29922
29925
|
} catch {
|
|
29923
29926
|
}
|
|
29924
29927
|
const result = await doReloadConfig(config, deps, provider);
|
|
29925
29928
|
try {
|
|
29926
|
-
fs41.appendFileSync(
|
|
29929
|
+
fs41.appendFileSync(path44.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] RELOAD DONE: ok=${result.ok} changes=${result.changes.join(",")}
|
|
29927
29930
|
`);
|
|
29928
29931
|
} catch {
|
|
29929
29932
|
}
|
|
@@ -29932,14 +29935,14 @@ function startConfigWatcher(config, deps, provider) {
|
|
|
29932
29935
|
watcher.on("error", (err) => {
|
|
29933
29936
|
console.error(`[config-watch] error: ${err.message}`);
|
|
29934
29937
|
try {
|
|
29935
|
-
fs41.appendFileSync(
|
|
29938
|
+
fs41.appendFileSync(path44.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] ERROR: ${err.message}
|
|
29936
29939
|
`);
|
|
29937
29940
|
} catch {
|
|
29938
29941
|
}
|
|
29939
29942
|
});
|
|
29940
29943
|
console.log(`[config-watch] watching ${configPath}`);
|
|
29941
29944
|
try {
|
|
29942
|
-
fs41.appendFileSync(
|
|
29945
|
+
fs41.appendFileSync(path44.join(config.stateDir, "logs", "engine-config-watch.log"), `[${(/* @__PURE__ */ new Date()).toISOString()}] STARTED watching=${configPath}
|
|
29943
29946
|
`);
|
|
29944
29947
|
} catch {
|
|
29945
29948
|
}
|