chatlab-cli 0.21.1 → 0.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/{chunk-OQVKZTVD.mjs → chunk-3UBWLWXB.mjs} +2 -2
- package/dist/{chunk-AIR7EAF4.mjs → chunk-4U45E7TO.mjs} +2 -2
- package/dist/{chunk-OZWXLRJL.mjs → chunk-6GLMVWGA.mjs} +24 -15
- package/dist/chunk-6GLMVWGA.mjs.map +1 -0
- package/dist/{chunk-2AIOU3PW.mjs → chunk-6NB475AA.mjs} +12 -3
- package/dist/chunk-6NB475AA.mjs.map +1 -0
- package/dist/{chunk-LI4X52E7.mjs → chunk-AMMSVJG4.mjs} +325 -94
- package/dist/chunk-AMMSVJG4.mjs.map +1 -0
- package/dist/{chunk-4GI2UPCS.mjs → chunk-D2XJ4Z7G.mjs} +2 -2
- package/dist/{chunk-7HQWGLX6.mjs → chunk-QJQJIUUS.mjs} +102 -96
- package/dist/chunk-QJQJIUUS.mjs.map +1 -0
- package/dist/chunk-VSOWNKPA.mjs +49 -0
- package/dist/cli.mjs +4 -3
- package/dist/{http-DHQI4G5J.mjs → http-R5UECMPJ.mjs} +8 -7
- package/dist/{import-CQWGIMZQ.mjs → import-3LOWRXWA.mjs} +5 -4
- package/dist/index.mjs +8 -7
- package/dist/{mcp-7Q3FEI3Z.mjs → mcp-WBHNLED2.mjs} +8 -7
- package/dist/mcp-WBHNLED2.mjs.map +1 -0
- package/dist/{src-QBT5SYW5.mjs → src-UHM2UDRD.mjs} +3 -2
- package/dist/{stream-import-VG7RP6KJ.mjs → stream-import-V6Z7DXSW.mjs} +4 -3
- package/dist/stream-import-V6Z7DXSW.mjs.map +1 -0
- package/dist/update-checker-MQMQ6A4B.mjs +191 -0
- package/dist/update-checker-MQMQ6A4B.mjs.map +1 -0
- package/dist-web/assets/{DebugToolsPanel-CoBtqb--.css → DebugToolsPanel-DkbsB6lr.css} +1 -1
- package/dist-web/assets/{DebugToolsPanel.vue_vue_type_script_setup_true_lang-CpFGhsl5.js → DebugToolsPanel.vue_vue_type_script_setup_true_lang-CxYyne-Q.js} +5 -5
- package/dist-web/assets/{EChartWordcloud-BYLFxPAX.js → EChartWordcloud-Ubal_aYg.js} +1 -1
- package/dist-web/assets/{MessageExportModal-DTgxz1eQ.js → MessageExportModal-De5_tX6a.js} +1 -1
- package/dist-web/assets/{electron-CTK4NJag.js → electron-CRSL7qPM.js} +1 -1
- package/dist-web/assets/{fetch-C2vUkdnA.js → fetch-Q-PqsiMb.js} +1 -1
- package/dist-web/assets/{fetch-CTZXLLcn.js → fetch-cFjLAPG2.js} +1 -1
- package/dist-web/assets/{index-DeG0EHOT.js → index-BJUGnYn5.js} +1 -1
- package/dist-web/assets/{index-DuhN8jAf.js → index-B_31fXeB.js} +2 -2
- package/dist-web/assets/index-CbOwHYzO.css +1 -0
- package/dist-web/assets/index-DKMUn8F5.js +173 -0
- package/dist-web/assets/{index-C4B0hv6C.js → index-D_ksezTw.js} +4 -4
- package/dist-web/assets/index-Dhg3SDb6.js +7 -0
- package/dist-web/assets/logo-DXIuG_WE.svg +17 -0
- package/dist-web/assets/{vendor-echarts-C13vDgZW.js → vendor-echarts-C5u62NnM.js} +1 -1
- package/dist-web/assets/{vendor-echarts-wordcloud-uVdwYsYa.js → vendor-echarts-wordcloud-CZ9gsX8l.js} +1 -1
- package/dist-web/assets/{vendor-nuxt-ui-CYMNNdeD.js → vendor-nuxt-ui-7OAuiz_i.js} +1 -1
- package/dist-web/assets/{vendor-zrender-5DcYjSZk.js → vendor-zrender-DFl4U2Oe.js} +1 -1
- package/dist-web/assets/{web-DImo6Kjz.js → web-CZe0Ismu.js} +1 -1
- package/dist-web/index.html +3 -3
- package/package.json +4 -3
- package/dist/chunk-2AIOU3PW.mjs.map +0 -1
- package/dist/chunk-7HQWGLX6.mjs.map +0 -1
- package/dist/chunk-LI4X52E7.mjs.map +0 -1
- package/dist/chunk-OZWXLRJL.mjs.map +0 -1
- package/dist/mcp-7Q3FEI3Z.mjs.map +0 -1
- package/dist-web/assets/index-B8867dX7.css +0 -1
- package/dist-web/assets/index-DUXf21MT.js +0 -173
- package/dist-web/assets/index-DZiH2cC1.js +0 -7
- /package/dist/{chunk-OQVKZTVD.mjs.map → chunk-3UBWLWXB.mjs.map} +0 -0
- /package/dist/{chunk-AIR7EAF4.mjs.map → chunk-4U45E7TO.mjs.map} +0 -0
- /package/dist/{chunk-4GI2UPCS.mjs.map → chunk-D2XJ4Z7G.mjs.map} +0 -0
- /package/dist/{http-DHQI4G5J.mjs.map → chunk-VSOWNKPA.mjs.map} +0 -0
- /package/dist/{import-CQWGIMZQ.mjs.map → http-R5UECMPJ.mjs.map} +0 -0
- /package/dist/{src-QBT5SYW5.mjs.map → import-3LOWRXWA.mjs.map} +0 -0
- /package/dist/{stream-import-VG7RP6KJ.mjs.map → src-UHM2UDRD.mjs.map} +0 -0
|
@@ -7,20 +7,21 @@ const __dirname = __pathDirname(__filename);
|
|
|
7
7
|
import {
|
|
8
8
|
importData,
|
|
9
9
|
parseFile
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-3UBWLWXB.mjs";
|
|
11
11
|
import {
|
|
12
12
|
analyzeIncrementalImport,
|
|
13
13
|
analyzeNewImport,
|
|
14
14
|
incrementalImport,
|
|
15
15
|
streamImport
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-4U45E7TO.mjs";
|
|
17
17
|
import {
|
|
18
18
|
AGENT_TOOL_REGISTRY,
|
|
19
19
|
CoreDataProvider
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-D2XJ4Z7G.mjs";
|
|
21
21
|
import {
|
|
22
|
-
getVersion
|
|
23
|
-
|
|
22
|
+
getVersion,
|
|
23
|
+
resolveCliPath
|
|
24
|
+
} from "./chunk-6NB475AA.mjs";
|
|
24
25
|
import {
|
|
25
26
|
AIConversationManager,
|
|
26
27
|
ALL_MIGRATIONS,
|
|
@@ -114,11 +115,10 @@ import {
|
|
|
114
115
|
verifyCliDataPath,
|
|
115
116
|
writeAuthProfile,
|
|
116
117
|
writeConfigField
|
|
117
|
-
} from "./chunk-
|
|
118
|
+
} from "./chunk-QJQJIUUS.mjs";
|
|
118
119
|
|
|
119
120
|
// src/http/index.ts
|
|
120
121
|
import * as fs14 from "fs";
|
|
121
|
-
import * as path15 from "path";
|
|
122
122
|
import * as crypto5 from "crypto";
|
|
123
123
|
|
|
124
124
|
// src/http/server.ts
|
|
@@ -207,6 +207,10 @@ async function authHook(request, reply) {
|
|
|
207
207
|
if (!cachedToken) return;
|
|
208
208
|
if (request.url.startsWith("/_web/")) return;
|
|
209
209
|
if (webModeEnabled && !request.url.startsWith("/api/")) return;
|
|
210
|
+
return requireBearerToken(request, reply);
|
|
211
|
+
}
|
|
212
|
+
function requireBearerToken(request, reply) {
|
|
213
|
+
if (!cachedToken) return;
|
|
210
214
|
const authHeader = request.headers.authorization;
|
|
211
215
|
if (!authHeader || !authHeader.startsWith("Bearer ")) {
|
|
212
216
|
const err = unauthorized();
|
|
@@ -492,7 +496,7 @@ function registerSessionRoutes(server2, dbManager2) {
|
|
|
492
496
|
|
|
493
497
|
// src/http/routes/web/index.ts
|
|
494
498
|
import * as os3 from "os";
|
|
495
|
-
import * as
|
|
499
|
+
import * as path6 from "path";
|
|
496
500
|
|
|
497
501
|
// src/merger/merge-cache.ts
|
|
498
502
|
import * as fs from "fs";
|
|
@@ -653,7 +657,6 @@ function registerMemberRoutes(server2, adapter) {
|
|
|
653
657
|
|
|
654
658
|
// src/http/routes/web/helpers.ts
|
|
655
659
|
import * as fs2 from "fs";
|
|
656
|
-
import * as path2 from "path";
|
|
657
660
|
function parseTimeFilter(query) {
|
|
658
661
|
const { startTs, endTs, memberId } = query;
|
|
659
662
|
if (!startTs && !endTs && !memberId) return void 0;
|
|
@@ -665,7 +668,7 @@ function parseTimeFilter(query) {
|
|
|
665
668
|
}
|
|
666
669
|
function resolveNativeBinding() {
|
|
667
670
|
if (process.versions.electron) return void 0;
|
|
668
|
-
const nativePath =
|
|
671
|
+
const nativePath = resolveCliPath("native/better_sqlite3.node");
|
|
669
672
|
if (fs2.existsSync(nativePath)) return nativePath;
|
|
670
673
|
return void 0;
|
|
671
674
|
}
|
|
@@ -879,10 +882,10 @@ function registerSessionIndexRoutes(server2, adapter) {
|
|
|
879
882
|
|
|
880
883
|
// src/ai/llm-config.ts
|
|
881
884
|
import * as fs3 from "fs";
|
|
882
|
-
import * as
|
|
885
|
+
import * as path2 from "path";
|
|
883
886
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
884
887
|
function loadLlmConfig(aiDataDir) {
|
|
885
|
-
const configPath =
|
|
888
|
+
const configPath = path2.join(aiDataDir, "llm-config.json");
|
|
886
889
|
if (!fs3.existsSync(configPath)) {
|
|
887
890
|
return { configs: [], defaultAssistant: null, fastModel: null };
|
|
888
891
|
}
|
|
@@ -924,7 +927,7 @@ function getDefaultAssistantConfig(aiDataDir) {
|
|
|
924
927
|
}
|
|
925
928
|
var MAX_CONFIG_COUNT = 99;
|
|
926
929
|
function saveLlmConfig(aiDataDir, store) {
|
|
927
|
-
const configPath =
|
|
930
|
+
const configPath = path2.join(aiDataDir, "llm-config.json");
|
|
928
931
|
const toSave = {
|
|
929
932
|
...store,
|
|
930
933
|
configs: store.configs.map((c) => {
|
|
@@ -1028,7 +1031,7 @@ function setFastModelSlot(aiDataDir, slot) {
|
|
|
1028
1031
|
return { success: true };
|
|
1029
1032
|
}
|
|
1030
1033
|
function loadRawConfigStore(aiDataDir) {
|
|
1031
|
-
const configPath =
|
|
1034
|
+
const configPath = path2.join(aiDataDir, "llm-config.json");
|
|
1032
1035
|
if (!fs3.existsSync(configPath)) {
|
|
1033
1036
|
return { configs: [], defaultAssistant: null, fastModel: null };
|
|
1034
1037
|
}
|
|
@@ -1088,13 +1091,13 @@ function registerSummaryRoutes(server2, dbManager2, adapter) {
|
|
|
1088
1091
|
// src/http/routes/web/import.ts
|
|
1089
1092
|
import * as fs4 from "fs";
|
|
1090
1093
|
import * as os from "os";
|
|
1091
|
-
import * as
|
|
1094
|
+
import * as path3 from "path";
|
|
1092
1095
|
var DEMO_BASE_URL = "https://chatlab.fun/assets/demo";
|
|
1093
1096
|
function cleanupTemp(...paths) {
|
|
1094
1097
|
for (const p of paths) {
|
|
1095
1098
|
try {
|
|
1096
|
-
const
|
|
1097
|
-
if (
|
|
1099
|
+
const stat2 = fs4.statSync(p);
|
|
1100
|
+
if (stat2.isDirectory()) {
|
|
1098
1101
|
fs4.rmSync(p, { recursive: true, force: true });
|
|
1099
1102
|
} else {
|
|
1100
1103
|
fs4.unlinkSync(p);
|
|
@@ -1110,8 +1113,8 @@ function registerImportRoutes(server2, dbManager2) {
|
|
|
1110
1113
|
server2.post("/_web/detect-format", async (request, reply) => {
|
|
1111
1114
|
const data = await request.file();
|
|
1112
1115
|
if (!data) return reply.code(400).send({ error: "No file uploaded" });
|
|
1113
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1114
|
-
const tmpPath =
|
|
1116
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-detect-"));
|
|
1117
|
+
const tmpPath = path3.join(tmpDir, data.filename || "upload");
|
|
1115
1118
|
try {
|
|
1116
1119
|
const chunks = [];
|
|
1117
1120
|
for await (const chunk of data.file) {
|
|
@@ -1128,8 +1131,8 @@ function registerImportRoutes(server2, dbManager2) {
|
|
|
1128
1131
|
server2.post("/_web/scan-multi-chat", async (request, reply) => {
|
|
1129
1132
|
const data = await request.file();
|
|
1130
1133
|
if (!data) return reply.code(400).send({ error: "No file uploaded" });
|
|
1131
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1132
|
-
const tmpPath =
|
|
1134
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-scan-"));
|
|
1135
|
+
const tmpPath = path3.join(tmpDir, data.filename || "upload");
|
|
1133
1136
|
try {
|
|
1134
1137
|
const chunks = [];
|
|
1135
1138
|
for await (const chunk of data.file) {
|
|
@@ -1145,8 +1148,8 @@ function registerImportRoutes(server2, dbManager2) {
|
|
|
1145
1148
|
server2.post("/_web/import", async (request, reply) => {
|
|
1146
1149
|
const data = await request.file();
|
|
1147
1150
|
if (!data) return reply.code(400).send({ error: "No file uploaded" });
|
|
1148
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1149
|
-
const tmpPath =
|
|
1151
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-import-"));
|
|
1152
|
+
const tmpPath = path3.join(tmpDir, data.filename || "upload");
|
|
1150
1153
|
const chunks = [];
|
|
1151
1154
|
for await (const chunk of data.file) {
|
|
1152
1155
|
chunks.push(chunk);
|
|
@@ -1194,7 +1197,7 @@ data: ${JSON.stringify(eventData)}
|
|
|
1194
1197
|
server2.post("/_web/import-directory", async (request, reply) => {
|
|
1195
1198
|
const parts = request.parts();
|
|
1196
1199
|
if (!parts) return reply.code(400).send({ error: "No files uploaded" });
|
|
1197
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1200
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-dir-import-"));
|
|
1198
1201
|
const relativePaths = [];
|
|
1199
1202
|
const fileBuffers = [];
|
|
1200
1203
|
try {
|
|
@@ -1222,9 +1225,9 @@ data: ${JSON.stringify(eventData)}
|
|
|
1222
1225
|
if (segments.length > 1) {
|
|
1223
1226
|
relPath = segments.slice(1).join("/");
|
|
1224
1227
|
}
|
|
1225
|
-
const targetPath =
|
|
1226
|
-
if (!targetPath.startsWith(tmpDir +
|
|
1227
|
-
fs4.mkdirSync(
|
|
1228
|
+
const targetPath = path3.resolve(tmpDir, relPath);
|
|
1229
|
+
if (!targetPath.startsWith(tmpDir + path3.sep)) continue;
|
|
1230
|
+
fs4.mkdirSync(path3.dirname(targetPath), { recursive: true });
|
|
1228
1231
|
fs4.writeFileSync(targetPath, fileBuffers[i].data);
|
|
1229
1232
|
}
|
|
1230
1233
|
const entryPath = findEntryFileInDirectory(tmpDir);
|
|
@@ -1270,8 +1273,8 @@ data: ${JSON.stringify({ success: false, error: err instanceof Error ? err.messa
|
|
|
1270
1273
|
const sessionId = request.params.id;
|
|
1271
1274
|
const data = await request.file();
|
|
1272
1275
|
if (!data) return reply.code(400).send({ error: "No file uploaded" });
|
|
1273
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1274
|
-
const tmpPath =
|
|
1276
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-inc-"));
|
|
1277
|
+
const tmpPath = path3.join(tmpDir, data.filename || "upload");
|
|
1275
1278
|
const chunks = [];
|
|
1276
1279
|
for await (const chunk of data.file) {
|
|
1277
1280
|
chunks.push(chunk);
|
|
@@ -1308,8 +1311,8 @@ data: ${JSON.stringify(eventData)}
|
|
|
1308
1311
|
const sessionId = request.params.id;
|
|
1309
1312
|
const data = await request.file();
|
|
1310
1313
|
if (!data) return reply.code(400).send({ error: "No file uploaded" });
|
|
1311
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1312
|
-
const tmpPath =
|
|
1314
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-analyze-"));
|
|
1315
|
+
const tmpPath = path3.join(tmpDir, data.filename || "upload");
|
|
1313
1316
|
const chunks = [];
|
|
1314
1317
|
for await (const chunk of data.file) {
|
|
1315
1318
|
chunks.push(chunk);
|
|
@@ -1326,8 +1329,8 @@ data: ${JSON.stringify(eventData)}
|
|
|
1326
1329
|
server2.post("/_web/import/analyze", async (request, reply) => {
|
|
1327
1330
|
const data = await request.file();
|
|
1328
1331
|
if (!data) return reply.code(400).send({ error: "No file uploaded" });
|
|
1329
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1330
|
-
const tmpPath =
|
|
1332
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-analyze-"));
|
|
1333
|
+
const tmpPath = path3.join(tmpDir, data.filename || "upload");
|
|
1331
1334
|
const chunks = [];
|
|
1332
1335
|
for await (const chunk of data.file) {
|
|
1333
1336
|
chunks.push(chunk);
|
|
@@ -1355,9 +1358,9 @@ data: ${JSON.stringify(eventData)}
|
|
|
1355
1358
|
|
|
1356
1359
|
`);
|
|
1357
1360
|
}
|
|
1358
|
-
const tmpDir = fs4.mkdtempSync(
|
|
1359
|
-
const groupPath =
|
|
1360
|
-
const privatePath =
|
|
1361
|
+
const tmpDir = fs4.mkdtempSync(path3.join(os.tmpdir(), "chatlab-demo-"));
|
|
1362
|
+
const groupPath = path3.join(tmpDir, "demo-group.json");
|
|
1363
|
+
const privatePath = path3.join(tmpDir, "demo-private.json");
|
|
1361
1364
|
try {
|
|
1362
1365
|
sendEvent("progress", { stage: "downloading", current: 1, total: 2 });
|
|
1363
1366
|
const groupResp = await fetch(`${DEMO_BASE_URL}/${locale}/demo-group.json`, {
|
|
@@ -1397,13 +1400,13 @@ data: ${JSON.stringify(eventData)}
|
|
|
1397
1400
|
// src/http/routes/web/merge.ts
|
|
1398
1401
|
import * as fs5 from "fs";
|
|
1399
1402
|
import * as os2 from "os";
|
|
1400
|
-
import * as
|
|
1403
|
+
import * as path4 from "path";
|
|
1401
1404
|
function registerMergeRoutes(server2, dbManager2, mergeCache) {
|
|
1402
1405
|
server2.post("/_web/merge/parse", async (request, reply) => {
|
|
1403
1406
|
const data = await request.file();
|
|
1404
1407
|
if (!data) return reply.code(400).send({ error: "No file uploaded" });
|
|
1405
|
-
const tmpDir = fs5.mkdtempSync(
|
|
1406
|
-
const tmpPath =
|
|
1408
|
+
const tmpDir = fs5.mkdtempSync(path4.join(os2.tmpdir(), "chatlab-merge-"));
|
|
1409
|
+
const tmpPath = path4.join(tmpDir, data.filename || "upload");
|
|
1407
1410
|
const chunks = [];
|
|
1408
1411
|
for await (const chunk of data.file) {
|
|
1409
1412
|
chunks.push(chunk);
|
|
@@ -1412,7 +1415,7 @@ function registerMergeRoutes(server2, dbManager2, mergeCache) {
|
|
|
1412
1415
|
try {
|
|
1413
1416
|
const result = await streamParseFileInfo(tmpPath, {
|
|
1414
1417
|
createTempDatabase(sourceFilePath) {
|
|
1415
|
-
return mergeCache.createTempDatabase(
|
|
1418
|
+
return mergeCache.createTempDatabase(path4.basename(sourceFilePath));
|
|
1416
1419
|
},
|
|
1417
1420
|
onProgress() {
|
|
1418
1421
|
}
|
|
@@ -1477,10 +1480,10 @@ function registerMergeRoutes(server2, dbManager2, mergeCache) {
|
|
|
1477
1480
|
const merged = buildMergedOutput(dataSources, outputName);
|
|
1478
1481
|
let sessionId;
|
|
1479
1482
|
if (andImport) {
|
|
1480
|
-
const { streamImport: serverStreamImport } = await import("./stream-import-
|
|
1483
|
+
const { streamImport: serverStreamImport } = await import("./stream-import-V6Z7DXSW.mjs");
|
|
1481
1484
|
const jsonData = JSON.stringify(merged.chatLabData);
|
|
1482
|
-
const tmpDir = fs5.mkdtempSync(
|
|
1483
|
-
const tmpPath =
|
|
1485
|
+
const tmpDir = fs5.mkdtempSync(path4.join(os2.tmpdir(), "chatlab-merged-"));
|
|
1486
|
+
const tmpPath = path4.join(tmpDir, `${outputName}.json`);
|
|
1484
1487
|
fs5.writeFileSync(tmpPath, jsonData, "utf-8");
|
|
1485
1488
|
try {
|
|
1486
1489
|
const importResult = await serverStreamImport(dbManager2, tmpPath);
|
|
@@ -1530,7 +1533,7 @@ function registerMergeRoutes(server2, dbManager2, mergeCache) {
|
|
|
1530
1533
|
const db = ensureDb2(dbManager2, sid);
|
|
1531
1534
|
const exported = exportSessionToJson(db);
|
|
1532
1535
|
const { db: tempDb, tempDbPath } = mergeCache.createTempDatabase(exported.meta.name);
|
|
1533
|
-
const { TempDbWriter } = await import("./src-
|
|
1536
|
+
const { TempDbWriter } = await import("./src-UHM2UDRD.mjs");
|
|
1534
1537
|
const writer = new TempDbWriter(tempDb);
|
|
1535
1538
|
writer.writeMeta({
|
|
1536
1539
|
name: exported.meta.name,
|
|
@@ -1592,8 +1595,192 @@ function registerExportRoutes(server2, adapter) {
|
|
|
1592
1595
|
|
|
1593
1596
|
// src/http/routes/web/cache.ts
|
|
1594
1597
|
import * as fs6 from "fs";
|
|
1595
|
-
import * as
|
|
1596
|
-
|
|
1598
|
+
import * as fsp from "fs/promises";
|
|
1599
|
+
import * as path5 from "path";
|
|
1600
|
+
import { execFile } from "child_process";
|
|
1601
|
+
function runExecFile(file, args, runner = execFile) {
|
|
1602
|
+
return new Promise((resolve2, reject) => {
|
|
1603
|
+
runner(file, args, (error) => {
|
|
1604
|
+
if (error) {
|
|
1605
|
+
reject(error);
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1608
|
+
resolve2();
|
|
1609
|
+
});
|
|
1610
|
+
});
|
|
1611
|
+
}
|
|
1612
|
+
async function openDirectoryPath(dirPath, platform = process.platform, runner) {
|
|
1613
|
+
if (platform === "darwin") {
|
|
1614
|
+
await runExecFile("open", [dirPath], runner);
|
|
1615
|
+
} else if (platform === "win32") {
|
|
1616
|
+
await runExecFile("explorer.exe", [dirPath], runner);
|
|
1617
|
+
} else {
|
|
1618
|
+
await runExecFile("xdg-open", [dirPath], runner);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
async function showPathInFolder(filePath, platform = process.platform, runner) {
|
|
1622
|
+
if (platform === "darwin") {
|
|
1623
|
+
await runExecFile("open", ["-R", filePath], runner);
|
|
1624
|
+
} else if (platform === "win32") {
|
|
1625
|
+
await runExecFile("explorer.exe", [`/select,${filePath}`], runner);
|
|
1626
|
+
} else {
|
|
1627
|
+
await runExecFile("xdg-open", [path5.dirname(filePath)], runner);
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
async function getDirSize(dirPath) {
|
|
1631
|
+
let totalSize = 0;
|
|
1632
|
+
try {
|
|
1633
|
+
if (!fs6.existsSync(dirPath)) return 0;
|
|
1634
|
+
const files = await fsp.readdir(dirPath, { withFileTypes: true });
|
|
1635
|
+
for (const file of files) {
|
|
1636
|
+
const filePath = path5.join(dirPath, file.name);
|
|
1637
|
+
if (file.isDirectory()) {
|
|
1638
|
+
totalSize += await getDirSize(filePath);
|
|
1639
|
+
} else {
|
|
1640
|
+
const stat2 = await fsp.stat(filePath);
|
|
1641
|
+
totalSize += stat2.size;
|
|
1642
|
+
}
|
|
1643
|
+
}
|
|
1644
|
+
} catch {
|
|
1645
|
+
}
|
|
1646
|
+
return totalSize;
|
|
1647
|
+
}
|
|
1648
|
+
async function getFileCount(dirPath) {
|
|
1649
|
+
let count = 0;
|
|
1650
|
+
try {
|
|
1651
|
+
if (!fs6.existsSync(dirPath)) return 0;
|
|
1652
|
+
const files = await fsp.readdir(dirPath, { withFileTypes: true });
|
|
1653
|
+
for (const file of files) {
|
|
1654
|
+
const filePath = path5.join(dirPath, file.name);
|
|
1655
|
+
if (file.isDirectory()) {
|
|
1656
|
+
count += await getFileCount(filePath);
|
|
1657
|
+
} else {
|
|
1658
|
+
count++;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
} catch {
|
|
1662
|
+
}
|
|
1663
|
+
return count;
|
|
1664
|
+
}
|
|
1665
|
+
function registerCacheRoutes(server2, pathProvider) {
|
|
1666
|
+
const downloadsDir = pathProvider.getDownloadsDir();
|
|
1667
|
+
server2.get("/_web/cache/info", async () => {
|
|
1668
|
+
const directories = [
|
|
1669
|
+
{
|
|
1670
|
+
id: "databases",
|
|
1671
|
+
name: "settings.storage.cache.databases.name",
|
|
1672
|
+
description: "settings.storage.cache.databases.description",
|
|
1673
|
+
path: pathProvider.getDatabaseDir(),
|
|
1674
|
+
icon: "i-heroicons-circle-stack",
|
|
1675
|
+
canClear: false
|
|
1676
|
+
},
|
|
1677
|
+
{
|
|
1678
|
+
id: "ai",
|
|
1679
|
+
name: "settings.storage.cache.ai.name",
|
|
1680
|
+
description: "settings.storage.cache.ai.description",
|
|
1681
|
+
path: pathProvider.getAiDataDir(),
|
|
1682
|
+
icon: "i-heroicons-sparkles",
|
|
1683
|
+
canClear: false
|
|
1684
|
+
},
|
|
1685
|
+
{
|
|
1686
|
+
id: "cache",
|
|
1687
|
+
name: "settings.storage.cache.statsCache.name",
|
|
1688
|
+
description: "settings.storage.cache.statsCache.description",
|
|
1689
|
+
path: pathProvider.getCacheDir(),
|
|
1690
|
+
icon: "i-heroicons-bolt",
|
|
1691
|
+
canClear: true
|
|
1692
|
+
},
|
|
1693
|
+
{
|
|
1694
|
+
id: "logs",
|
|
1695
|
+
name: "settings.storage.cache.logs.name",
|
|
1696
|
+
description: "settings.storage.cache.logs.description",
|
|
1697
|
+
path: pathProvider.getLogsDir(),
|
|
1698
|
+
icon: "i-heroicons-document-text",
|
|
1699
|
+
canClear: true
|
|
1700
|
+
}
|
|
1701
|
+
];
|
|
1702
|
+
const results = await Promise.all(
|
|
1703
|
+
directories.map(async (dir) => {
|
|
1704
|
+
const [size, fileCount] = await Promise.all([getDirSize(dir.path), getFileCount(dir.path)]);
|
|
1705
|
+
return { ...dir, size, fileCount, exists: fs6.existsSync(dir.path) };
|
|
1706
|
+
})
|
|
1707
|
+
);
|
|
1708
|
+
return {
|
|
1709
|
+
baseDir: pathProvider.getUserDataDir(),
|
|
1710
|
+
systemDir: pathProvider.getSystemDir(),
|
|
1711
|
+
directories: results,
|
|
1712
|
+
totalSize: results.reduce((sum, d) => sum + d.size, 0)
|
|
1713
|
+
};
|
|
1714
|
+
});
|
|
1715
|
+
server2.post("/_web/cache/clear", async (request) => {
|
|
1716
|
+
const { cacheId } = request.body;
|
|
1717
|
+
const allowedDirs = {
|
|
1718
|
+
cache: pathProvider.getCacheDir(),
|
|
1719
|
+
logs: pathProvider.getLogsDir()
|
|
1720
|
+
};
|
|
1721
|
+
const dirPath = allowedDirs[cacheId];
|
|
1722
|
+
if (!dirPath) return { success: false, error: "Not allowed to clear this directory" };
|
|
1723
|
+
if (!fs6.existsSync(dirPath)) return { success: true };
|
|
1724
|
+
const files = await fsp.readdir(dirPath);
|
|
1725
|
+
for (const file of files) {
|
|
1726
|
+
const filePath = path5.join(dirPath, file);
|
|
1727
|
+
const stat2 = await fsp.stat(filePath);
|
|
1728
|
+
if (stat2.isDirectory()) {
|
|
1729
|
+
await fsp.rm(filePath, { recursive: true });
|
|
1730
|
+
} else {
|
|
1731
|
+
await fsp.unlink(filePath);
|
|
1732
|
+
}
|
|
1733
|
+
}
|
|
1734
|
+
return { success: true };
|
|
1735
|
+
});
|
|
1736
|
+
server2.post("/_web/cache/open-dir", async (request) => {
|
|
1737
|
+
const { cacheId } = request.body;
|
|
1738
|
+
const dirPaths = {
|
|
1739
|
+
base: pathProvider.getUserDataDir(),
|
|
1740
|
+
system: pathProvider.getSystemDir(),
|
|
1741
|
+
databases: pathProvider.getDatabaseDir(),
|
|
1742
|
+
cache: pathProvider.getCacheDir(),
|
|
1743
|
+
ai: pathProvider.getAiDataDir(),
|
|
1744
|
+
logs: pathProvider.getLogsDir(),
|
|
1745
|
+
downloads: downloadsDir
|
|
1746
|
+
};
|
|
1747
|
+
const dirPath = dirPaths[cacheId];
|
|
1748
|
+
if (!dirPath) return { success: false, error: "Unknown directory" };
|
|
1749
|
+
if (!fs6.existsSync(dirPath)) {
|
|
1750
|
+
await fsp.mkdir(dirPath, { recursive: true });
|
|
1751
|
+
}
|
|
1752
|
+
try {
|
|
1753
|
+
await openDirectoryPath(dirPath);
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1756
|
+
}
|
|
1757
|
+
return { success: true };
|
|
1758
|
+
});
|
|
1759
|
+
server2.get("/_web/cache/data-dir", async () => {
|
|
1760
|
+
const config = loadConfig();
|
|
1761
|
+
const isCustom = Boolean(config.data.user_data_dir || process.env.CHATLAB_DATA_DIR);
|
|
1762
|
+
return { path: pathProvider.getUserDataDir(), isCustom };
|
|
1763
|
+
});
|
|
1764
|
+
server2.get("/_web/cache/latest-import-log", async () => {
|
|
1765
|
+
const importLogDir = path5.join(pathProvider.getLogsDir(), "import");
|
|
1766
|
+
if (!fs6.existsSync(importLogDir)) {
|
|
1767
|
+
return { success: false, error: "Log directory not found" };
|
|
1768
|
+
}
|
|
1769
|
+
const files = await fsp.readdir(importLogDir);
|
|
1770
|
+
const logFiles = files.filter((f) => f.startsWith("import_") && f.endsWith(".log"));
|
|
1771
|
+
if (logFiles.length === 0) {
|
|
1772
|
+
return { success: false, error: "No import logs found" };
|
|
1773
|
+
}
|
|
1774
|
+
const fileStats = await Promise.all(
|
|
1775
|
+
logFiles.map(async (f) => {
|
|
1776
|
+
const filePath = path5.join(importLogDir, f);
|
|
1777
|
+
const stat2 = await fsp.stat(filePath);
|
|
1778
|
+
return { name: f, path: filePath, mtime: stat2.mtime.getTime() };
|
|
1779
|
+
})
|
|
1780
|
+
);
|
|
1781
|
+
fileStats.sort((a, b) => b.mtime - a.mtime);
|
|
1782
|
+
return { success: true, path: fileStats[0].path, name: fileStats[0].name };
|
|
1783
|
+
});
|
|
1597
1784
|
server2.post("/_web/cache/save-to-downloads", async (request) => {
|
|
1598
1785
|
const { filename, dataUrl } = request.body;
|
|
1599
1786
|
if (!filename || !dataUrl) {
|
|
@@ -1605,7 +1792,7 @@ function registerCacheRoutes(server2, downloadsDir) {
|
|
|
1605
1792
|
if (!fs6.existsSync(downloadsDir)) {
|
|
1606
1793
|
fs6.mkdirSync(downloadsDir, { recursive: true });
|
|
1607
1794
|
}
|
|
1608
|
-
const filePath =
|
|
1795
|
+
const filePath = path5.join(downloadsDir, filename);
|
|
1609
1796
|
fs6.writeFileSync(filePath, buffer);
|
|
1610
1797
|
return { success: true, filePath };
|
|
1611
1798
|
});
|
|
@@ -1614,26 +1801,46 @@ function registerCacheRoutes(server2, downloadsDir) {
|
|
|
1614
1801
|
if (!filePath) {
|
|
1615
1802
|
return { success: false, error: "filePath is required" };
|
|
1616
1803
|
}
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
exec(`open -R "${filePath}"`);
|
|
1622
|
-
} else if (platform === "win32") {
|
|
1623
|
-
exec(`explorer /select,"${filePath}"`);
|
|
1624
|
-
} else {
|
|
1625
|
-
exec(`xdg-open "${dir}"`);
|
|
1804
|
+
try {
|
|
1805
|
+
await showPathInFolder(filePath);
|
|
1806
|
+
} catch (error) {
|
|
1807
|
+
return { success: false, error: error instanceof Error ? error.message : String(error) };
|
|
1626
1808
|
}
|
|
1627
1809
|
return { success: true };
|
|
1628
1810
|
});
|
|
1629
1811
|
}
|
|
1630
1812
|
|
|
1631
1813
|
// src/http/routes/web/index.ts
|
|
1814
|
+
function isNewerVersion(latest, current) {
|
|
1815
|
+
const parse = (v) => {
|
|
1816
|
+
const [core, pre] = v.split("-", 2);
|
|
1817
|
+
const parts = core.split(".").map(Number);
|
|
1818
|
+
return { major: parts[0] || 0, minor: parts[1] || 0, patch: parts[2] || 0, pre };
|
|
1819
|
+
};
|
|
1820
|
+
const l = parse(latest);
|
|
1821
|
+
const c = parse(current);
|
|
1822
|
+
if (l.major !== c.major) return l.major > c.major;
|
|
1823
|
+
if (l.minor !== c.minor) return l.minor > c.minor;
|
|
1824
|
+
if (l.patch !== c.patch) return l.patch > c.patch;
|
|
1825
|
+
if (c.pre && !l.pre) return true;
|
|
1826
|
+
return false;
|
|
1827
|
+
}
|
|
1632
1828
|
function registerWebRoutes(server2, dbManager2, options) {
|
|
1633
1829
|
const adapter = createDatabaseManagerAdapter(dbManager2);
|
|
1634
1830
|
const mergeCache = options?.pathProvider ? new MergeSessionCache(options.pathProvider, { nativeBinding: options.nativeBinding }) : null;
|
|
1635
1831
|
mergeCache?.cleanupOrphans();
|
|
1636
|
-
const
|
|
1832
|
+
const fallbackPathProvider = {
|
|
1833
|
+
getSystemDir: () => path6.join(os3.homedir(), ".chatlab"),
|
|
1834
|
+
getUserDataDir: () => path6.join(os3.homedir(), ".chatlab", "data"),
|
|
1835
|
+
getDatabaseDir: () => path6.join(os3.homedir(), ".chatlab", "data", "databases"),
|
|
1836
|
+
getAiDataDir: () => path6.join(os3.homedir(), ".chatlab", "ai"),
|
|
1837
|
+
getSettingsDir: () => path6.join(os3.homedir(), ".chatlab", "settings"),
|
|
1838
|
+
getCacheDir: () => path6.join(os3.homedir(), ".chatlab", "cache"),
|
|
1839
|
+
getTempDir: () => path6.join(os3.homedir(), ".chatlab", "temp"),
|
|
1840
|
+
getLogsDir: () => path6.join(os3.homedir(), ".chatlab", "logs"),
|
|
1841
|
+
getDownloadsDir: () => path6.join(os3.homedir(), "Downloads")
|
|
1842
|
+
};
|
|
1843
|
+
const resolvedPathProvider = options?.pathProvider ?? fallbackPathProvider;
|
|
1637
1844
|
registerSessionRoutes2(server2, adapter);
|
|
1638
1845
|
registerMemberRoutes(server2, adapter);
|
|
1639
1846
|
registerAnalyticsRoutes(server2, dbManager2, adapter);
|
|
@@ -1645,11 +1852,34 @@ function registerWebRoutes(server2, dbManager2, options) {
|
|
|
1645
1852
|
registerMergeRoutes(server2, dbManager2, mergeCache);
|
|
1646
1853
|
}
|
|
1647
1854
|
registerExportRoutes(server2, adapter);
|
|
1648
|
-
registerCacheRoutes(server2,
|
|
1855
|
+
registerCacheRoutes(server2, resolvedPathProvider);
|
|
1856
|
+
server2.get("/_web/system/check-update", async () => {
|
|
1857
|
+
const currentVersion = getVersion();
|
|
1858
|
+
const packageName = "chatlab-cli";
|
|
1859
|
+
try {
|
|
1860
|
+
const resp = await fetch(`https://registry.npmjs.org/${packageName}/latest`, {
|
|
1861
|
+
headers: { Accept: "application/json" },
|
|
1862
|
+
signal: AbortSignal.timeout(1e4)
|
|
1863
|
+
});
|
|
1864
|
+
if (!resp.ok) {
|
|
1865
|
+
return { hasUpdate: false, currentVersion, error: `npm registry HTTP ${resp.status}` };
|
|
1866
|
+
}
|
|
1867
|
+
const data = await resp.json();
|
|
1868
|
+
const latestVersion = data.version || currentVersion;
|
|
1869
|
+
const hasUpdate = isNewerVersion(latestVersion, currentVersion);
|
|
1870
|
+
return { hasUpdate, currentVersion, latestVersion };
|
|
1871
|
+
} catch (err) {
|
|
1872
|
+
return {
|
|
1873
|
+
hasUpdate: false,
|
|
1874
|
+
currentVersion,
|
|
1875
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1876
|
+
};
|
|
1877
|
+
}
|
|
1878
|
+
});
|
|
1649
1879
|
}
|
|
1650
1880
|
|
|
1651
1881
|
// src/http/routes/nlp.ts
|
|
1652
|
-
import * as
|
|
1882
|
+
import * as path7 from "path";
|
|
1653
1883
|
function ensureDb3(dbManager2, sessionId) {
|
|
1654
1884
|
const db = dbManager2.open(sessionId);
|
|
1655
1885
|
if (!db) {
|
|
@@ -1660,7 +1890,7 @@ function ensureDb3(dbManager2, sessionId) {
|
|
|
1660
1890
|
function registerNlpRoutes(server2, dbManager2) {
|
|
1661
1891
|
const pathProvider = dbManager2["pathProvider"];
|
|
1662
1892
|
if (pathProvider) {
|
|
1663
|
-
const nlpDir =
|
|
1893
|
+
const nlpDir = path7.join(pathProvider.getSystemDir(), "nlp");
|
|
1664
1894
|
initNlpDir(nlpDir);
|
|
1665
1895
|
ensureDefaultDict(nlpDir).catch((err) => console.warn("[NLP] Auto-download zh-CN dict failed:", err));
|
|
1666
1896
|
}
|
|
@@ -1698,12 +1928,12 @@ function registerNlpRoutes(server2, dbManager2) {
|
|
|
1698
1928
|
}
|
|
1699
1929
|
function resolveNlpDir(dbManager2) {
|
|
1700
1930
|
const pathProvider = dbManager2["pathProvider"];
|
|
1701
|
-
return
|
|
1931
|
+
return path7.join(pathProvider.getSystemDir(), "nlp");
|
|
1702
1932
|
}
|
|
1703
1933
|
|
|
1704
1934
|
// src/http/routes/ai.ts
|
|
1705
1935
|
import * as fs10 from "fs";
|
|
1706
|
-
import * as
|
|
1936
|
+
import * as path11 from "path";
|
|
1707
1937
|
|
|
1708
1938
|
// src/ai/logger.ts
|
|
1709
1939
|
var logger = null;
|
|
@@ -1752,6 +1982,7 @@ function adaptToolsForAgent(tools, getContext, options) {
|
|
|
1752
1982
|
description: tool.description,
|
|
1753
1983
|
parameters: convertJsonSchemaToParameters(tool.inputSchema),
|
|
1754
1984
|
async execute(_toolCallId, params) {
|
|
1985
|
+
const toolParams = params && typeof params === "object" ? params : {};
|
|
1755
1986
|
const ctx = getContext();
|
|
1756
1987
|
const execCtx = {
|
|
1757
1988
|
db: ctx.db,
|
|
@@ -1761,7 +1992,7 @@ function adaptToolsForAgent(tools, getContext, options) {
|
|
|
1761
1992
|
segmentText: (texts, locale, options2) => batchSegmentWithFrequency(texts, locale, options2)
|
|
1762
1993
|
};
|
|
1763
1994
|
try {
|
|
1764
|
-
const result = await tool.handler(
|
|
1995
|
+
const result = await tool.handler(toolParams, execCtx);
|
|
1765
1996
|
if (result.rawMessages && result.rawMessages.length > 0) {
|
|
1766
1997
|
const pipelineResult = applyPreprocessingPipeline({
|
|
1767
1998
|
rawMessages: result.rawMessages,
|
|
@@ -1784,9 +2015,9 @@ function adaptToolsForAgent(tools, getContext, options) {
|
|
|
1784
2015
|
|
|
1785
2016
|
// src/ai/assistant-loader.ts
|
|
1786
2017
|
import * as fs7 from "fs";
|
|
1787
|
-
import * as
|
|
2018
|
+
import * as path8 from "path";
|
|
1788
2019
|
function loadAssistantConfig(aiDataDir, assistantId) {
|
|
1789
|
-
const filePath =
|
|
2020
|
+
const filePath = path8.join(aiDataDir, "assistants", `${assistantId}.md`);
|
|
1790
2021
|
if (!fs7.existsSync(filePath)) return null;
|
|
1791
2022
|
try {
|
|
1792
2023
|
const content = fs7.readFileSync(filePath, "utf-8");
|
|
@@ -1798,7 +2029,7 @@ function loadAssistantConfig(aiDataDir, assistantId) {
|
|
|
1798
2029
|
|
|
1799
2030
|
// src/ai/manager-factory.ts
|
|
1800
2031
|
import * as fs8 from "fs";
|
|
1801
|
-
import * as
|
|
2032
|
+
import * as path9 from "path";
|
|
1802
2033
|
import { createHash, randomUUID as randomUUID3 } from "crypto";
|
|
1803
2034
|
var nodeFs = {
|
|
1804
2035
|
ensureDir(dir) {
|
|
@@ -1821,7 +2052,7 @@ var nodeFs = {
|
|
|
1821
2052
|
return fs8.existsSync(filePath);
|
|
1822
2053
|
},
|
|
1823
2054
|
joinPath(...parts) {
|
|
1824
|
-
return
|
|
2055
|
+
return path9.join(...parts);
|
|
1825
2056
|
}
|
|
1826
2057
|
};
|
|
1827
2058
|
var managerCache = /* @__PURE__ */ new Map();
|
|
@@ -1831,13 +2062,13 @@ function getAssistantManager(aiDataDir) {
|
|
|
1831
2062
|
cached = {
|
|
1832
2063
|
assistant: new AssistantManager({
|
|
1833
2064
|
fs: nodeFs,
|
|
1834
|
-
assistantsDir:
|
|
2065
|
+
assistantsDir: path9.join(aiDataDir, "assistants"),
|
|
1835
2066
|
builtinRawConfigs: [],
|
|
1836
2067
|
generateId: () => `custom_${randomUUID3().replace(/-/g, "").slice(0, 12)}`
|
|
1837
2068
|
}),
|
|
1838
2069
|
skill: new SkillManagerCore({
|
|
1839
2070
|
fs: nodeFs,
|
|
1840
|
-
skillsDir:
|
|
2071
|
+
skillsDir: path9.join(aiDataDir, "skills"),
|
|
1841
2072
|
builtinRawSkills: [],
|
|
1842
2073
|
contentHash: (content) => createHash("md5").update(content).digest("hex")
|
|
1843
2074
|
})
|
|
@@ -1980,10 +2211,10 @@ async function runServerAgent(options) {
|
|
|
1980
2211
|
|
|
1981
2212
|
// src/ai/custom-store.ts
|
|
1982
2213
|
import * as fs9 from "fs";
|
|
1983
|
-
import * as
|
|
2214
|
+
import * as path10 from "path";
|
|
1984
2215
|
import { randomUUID as randomUUID4 } from "crypto";
|
|
1985
2216
|
function readProviders(aiDataDir) {
|
|
1986
|
-
const storePath =
|
|
2217
|
+
const storePath = path10.join(aiDataDir, "custom-providers.json");
|
|
1987
2218
|
if (!fs9.existsSync(storePath)) return [];
|
|
1988
2219
|
try {
|
|
1989
2220
|
const content = fs9.readFileSync(storePath, "utf-8");
|
|
@@ -1993,8 +2224,8 @@ function readProviders(aiDataDir) {
|
|
|
1993
2224
|
}
|
|
1994
2225
|
}
|
|
1995
2226
|
function writeProviders(aiDataDir, providers) {
|
|
1996
|
-
const storePath =
|
|
1997
|
-
const dir =
|
|
2227
|
+
const storePath = path10.join(aiDataDir, "custom-providers.json");
|
|
2228
|
+
const dir = path10.dirname(storePath);
|
|
1998
2229
|
if (!fs9.existsSync(dir)) fs9.mkdirSync(dir, { recursive: true });
|
|
1999
2230
|
fs9.writeFileSync(storePath, JSON.stringify(providers, null, 2), "utf-8");
|
|
2000
2231
|
}
|
|
@@ -2027,7 +2258,7 @@ function deleteCustomProvider(aiDataDir, id) {
|
|
|
2027
2258
|
return { success: true };
|
|
2028
2259
|
}
|
|
2029
2260
|
function readModels(aiDataDir) {
|
|
2030
|
-
const storePath =
|
|
2261
|
+
const storePath = path10.join(aiDataDir, "custom-models.json");
|
|
2031
2262
|
if (!fs9.existsSync(storePath)) return [];
|
|
2032
2263
|
try {
|
|
2033
2264
|
const content = fs9.readFileSync(storePath, "utf-8");
|
|
@@ -2037,8 +2268,8 @@ function readModels(aiDataDir) {
|
|
|
2037
2268
|
}
|
|
2038
2269
|
}
|
|
2039
2270
|
function writeModels(aiDataDir, models) {
|
|
2040
|
-
const storePath =
|
|
2041
|
-
const dir =
|
|
2271
|
+
const storePath = path10.join(aiDataDir, "custom-models.json");
|
|
2272
|
+
const dir = path10.dirname(storePath);
|
|
2042
2273
|
if (!fs9.existsSync(dir)) fs9.mkdirSync(dir, { recursive: true });
|
|
2043
2274
|
fs9.writeFileSync(storePath, JSON.stringify(models, null, 2), "utf-8");
|
|
2044
2275
|
}
|
|
@@ -2154,7 +2385,7 @@ function registerAiRoutes(server2, dbManager2, convManager2) {
|
|
|
2154
2385
|
return mgr.getBuiltinCatalog();
|
|
2155
2386
|
});
|
|
2156
2387
|
server2.get("/_web/ai/llm/has-config", async () => {
|
|
2157
|
-
const configPath =
|
|
2388
|
+
const configPath = path11.join(getAiDir(dbManager2), "llm-config.json");
|
|
2158
2389
|
if (!fs10.existsSync(configPath)) return false;
|
|
2159
2390
|
try {
|
|
2160
2391
|
const data = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
|
|
@@ -2165,7 +2396,7 @@ function registerAiRoutes(server2, dbManager2, convManager2) {
|
|
|
2165
2396
|
}
|
|
2166
2397
|
});
|
|
2167
2398
|
server2.get("/_web/ai/llm/configs", async () => {
|
|
2168
|
-
const configPath =
|
|
2399
|
+
const configPath = path11.join(getAiDir(dbManager2), "llm-config.json");
|
|
2169
2400
|
if (!fs10.existsSync(configPath)) return { configs: [], defaultAssistant: null, fastModel: null };
|
|
2170
2401
|
try {
|
|
2171
2402
|
const data = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
|
|
@@ -2194,7 +2425,7 @@ function registerAiRoutes(server2, dbManager2, convManager2) {
|
|
|
2194
2425
|
});
|
|
2195
2426
|
});
|
|
2196
2427
|
server2.get("/_web/ai/llm/provider-registry", async () => {
|
|
2197
|
-
const customPath =
|
|
2428
|
+
const customPath = path11.join(getAiDir(dbManager2), "custom-providers.json");
|
|
2198
2429
|
let custom = [];
|
|
2199
2430
|
if (fs10.existsSync(customPath)) {
|
|
2200
2431
|
try {
|
|
@@ -2207,7 +2438,7 @@ function registerAiRoutes(server2, dbManager2, convManager2) {
|
|
|
2207
2438
|
return [...BUILTIN_PROVIDERS, ...custom];
|
|
2208
2439
|
});
|
|
2209
2440
|
server2.get("/_web/ai/llm/model-catalog", async () => {
|
|
2210
|
-
const customPath =
|
|
2441
|
+
const customPath = path11.join(getAiDir(dbManager2), "custom-models.json");
|
|
2211
2442
|
let custom = [];
|
|
2212
2443
|
if (fs10.existsSync(customPath)) {
|
|
2213
2444
|
try {
|
|
@@ -2220,7 +2451,7 @@ function registerAiRoutes(server2, dbManager2, convManager2) {
|
|
|
2220
2451
|
return [...BUILTIN_MODELS, ...custom];
|
|
2221
2452
|
});
|
|
2222
2453
|
server2.get("/_web/ai/llm/default-assistant-slot", async () => {
|
|
2223
|
-
const configPath =
|
|
2454
|
+
const configPath = path11.join(getAiDir(dbManager2), "llm-config.json");
|
|
2224
2455
|
if (!fs10.existsSync(configPath)) return null;
|
|
2225
2456
|
try {
|
|
2226
2457
|
const data = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
|
|
@@ -2230,7 +2461,7 @@ function registerAiRoutes(server2, dbManager2, convManager2) {
|
|
|
2230
2461
|
}
|
|
2231
2462
|
});
|
|
2232
2463
|
server2.get("/_web/ai/llm/fast-model-slot", async () => {
|
|
2233
|
-
const configPath =
|
|
2464
|
+
const configPath = path11.join(getAiDir(dbManager2), "llm-config.json");
|
|
2234
2465
|
if (!fs10.existsSync(configPath)) return null;
|
|
2235
2466
|
try {
|
|
2236
2467
|
const data = JSON.parse(fs10.readFileSync(configPath, "utf-8"));
|
|
@@ -2587,7 +2818,7 @@ var NOOP_LOGGER = { info: noop, warn: noop, error: noop };
|
|
|
2587
2818
|
|
|
2588
2819
|
// ../../packages/sync/src/data-source-manager.ts
|
|
2589
2820
|
import * as fs11 from "fs";
|
|
2590
|
-
import * as
|
|
2821
|
+
import * as path12 from "path";
|
|
2591
2822
|
import * as crypto2 from "crypto";
|
|
2592
2823
|
var CONFIG_FILE = "data-sources.json";
|
|
2593
2824
|
function generateId(prefix = "ds") {
|
|
@@ -2615,7 +2846,7 @@ var DataSourceManager = class {
|
|
|
2615
2846
|
this.logger = logger2 ?? NOOP_LOGGER;
|
|
2616
2847
|
}
|
|
2617
2848
|
getConfigPath() {
|
|
2618
|
-
return
|
|
2849
|
+
return path12.join(this.configDir, CONFIG_FILE);
|
|
2619
2850
|
}
|
|
2620
2851
|
ensureDir() {
|
|
2621
2852
|
fs11.mkdirSync(this.configDir, { recursive: true });
|
|
@@ -2904,10 +3135,10 @@ var PullEngine = class {
|
|
|
2904
3135
|
limit: ds.pullLimit
|
|
2905
3136
|
});
|
|
2906
3137
|
try {
|
|
2907
|
-
const
|
|
2908
|
-
this.logger.info(`[Pull] "${sess.name}" page ${pageCount}: fetched ${
|
|
3138
|
+
const stat2 = fs12.statSync(tempFile);
|
|
3139
|
+
this.logger.info(`[Pull] "${sess.name}" page ${pageCount}: fetched ${stat2.size} bytes`);
|
|
2909
3140
|
const sync0 = parseSyncFromFile(tempFile);
|
|
2910
|
-
if (
|
|
3141
|
+
if (stat2.size < 1024) {
|
|
2911
3142
|
if (!fileContainsMessages(tempFile) && sync0?.hasMore === false) {
|
|
2912
3143
|
cleanupTempFile(tempFile);
|
|
2913
3144
|
const retryDelays = [2e3, 3e3, 5e3];
|
|
@@ -2990,7 +3221,7 @@ var PullEngine = class {
|
|
|
2990
3221
|
continue;
|
|
2991
3222
|
}
|
|
2992
3223
|
}
|
|
2993
|
-
if (
|
|
3224
|
+
if (stat2.size === 0) {
|
|
2994
3225
|
cleanupTempFile(tempFile);
|
|
2995
3226
|
break;
|
|
2996
3227
|
}
|
|
@@ -3198,11 +3429,11 @@ function reloadTimer(dsId, skipInitialPull = false) {
|
|
|
3198
3429
|
// src/sync/adapters.ts
|
|
3199
3430
|
import * as fs13 from "fs";
|
|
3200
3431
|
import * as os4 from "os";
|
|
3201
|
-
import * as
|
|
3432
|
+
import * as path13 from "path";
|
|
3202
3433
|
import * as crypto4 from "crypto";
|
|
3203
3434
|
function getTempFilePath(ext) {
|
|
3204
3435
|
const id = crypto4.randomBytes(8).toString("hex");
|
|
3205
|
-
return
|
|
3436
|
+
return path13.join(os4.tmpdir(), `chatlab-pull-${id}${ext}`);
|
|
3206
3437
|
}
|
|
3207
3438
|
var NodeFetcher = class {
|
|
3208
3439
|
async fetchToTempFile(baseUrl, remoteSessionId, token, params) {
|
|
@@ -3225,7 +3456,7 @@ var NodeFetcher = class {
|
|
|
3225
3456
|
};
|
|
3226
3457
|
function resolveNativeBinding2() {
|
|
3227
3458
|
if (process.versions.electron) return void 0;
|
|
3228
|
-
const nativePath =
|
|
3459
|
+
const nativePath = resolveCliPath("native/better_sqlite3.node");
|
|
3229
3460
|
if (fs13.existsSync(nativePath)) return nativePath;
|
|
3230
3461
|
return void 0;
|
|
3231
3462
|
}
|
|
@@ -3456,7 +3687,7 @@ var dbManager = null;
|
|
|
3456
3687
|
var convManager = null;
|
|
3457
3688
|
function resolveNativeBinding3() {
|
|
3458
3689
|
if (process.versions.electron) return void 0;
|
|
3459
|
-
const nativePath =
|
|
3690
|
+
const nativePath = resolveCliPath("native/better_sqlite3.node");
|
|
3460
3691
|
if (fs14.existsSync(nativePath)) return nativePath;
|
|
3461
3692
|
return void 0;
|
|
3462
3693
|
}
|
|
@@ -3481,7 +3712,7 @@ async function startHttpServer(options) {
|
|
|
3481
3712
|
const pathProvider = new NodePathProvider(userDataDir);
|
|
3482
3713
|
pathProvider.ensureAllDirs();
|
|
3483
3714
|
if (hasPendingElectronDataWarning() || !verifyCliDataPath(pathProvider.getDatabaseDir())) {
|
|
3484
|
-
|
|
3715
|
+
console.error(
|
|
3485
3716
|
"\n" + "=".repeat(68) + "\n ChatLab: Electron desktop data not found\n" + "=".repeat(68) + '\n\n Detected that ChatLab desktop app was installed on this machine,\n but could not locate your chat databases.\n\n This usually means you changed the data directory in desktop settings.\n\n To fix this, choose one of:\n\n 1. Open ChatLab desktop app \u2014 it will auto-migrate your data\n 2. Set the data directory manually:\n export CHATLAB_DATA_DIR="/path/to/your/data"\n 3. Edit ~/.chatlab/config.toml:\n [data]\n user_data_dir = "/path/to/your/data"\n\n' + "=".repeat(68) + "\n"
|
|
3486
3717
|
);
|
|
3487
3718
|
}
|
|
@@ -3558,4 +3789,4 @@ export {
|
|
|
3558
3789
|
startHttpServer,
|
|
3559
3790
|
stopHttpServer
|
|
3560
3791
|
};
|
|
3561
|
-
//# sourceMappingURL=chunk-
|
|
3792
|
+
//# sourceMappingURL=chunk-AMMSVJG4.mjs.map
|