chatlab-cli 0.25.0 → 0.26.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/dist/chat-command-ZP4WJVWC.mjs +304 -0
- package/dist/chat-command-ZP4WJVWC.mjs.map +1 -0
- package/dist/{chunk-CIBTUWAE.mjs → chunk-6G7AIF7I.mjs} +38 -8
- package/dist/chunk-6G7AIF7I.mjs.map +1 -0
- package/dist/chunk-ILGSSXOG.mjs +549 -0
- package/dist/chunk-ILGSSXOG.mjs.map +1 -0
- package/dist/{chunk-E65ABM3C.mjs → chunk-IRZRIHIT.mjs} +100 -63
- package/dist/chunk-IRZRIHIT.mjs.map +1 -0
- package/dist/{chunk-4OMV4VNH.mjs → chunk-QY67NN65.mjs} +1900 -729
- package/dist/chunk-QY67NN65.mjs.map +1 -0
- package/dist/{chunk-FSHVDWI2.mjs → chunk-SJIOPSMM.mjs} +116 -569
- package/dist/chunk-SJIOPSMM.mjs.map +1 -0
- package/dist/{chunk-GNT5G74Z.mjs → chunk-TC74HESZ.mjs} +59 -33
- package/dist/chunk-TC74HESZ.mjs.map +1 -0
- package/dist/chunk-UB4XBM4R.mjs +40 -0
- package/dist/chunk-UB4XBM4R.mjs.map +1 -0
- package/dist/{chunk-TCPXAX3F.mjs → chunk-WXC6RZCX.mjs} +17 -25
- package/dist/chunk-WXC6RZCX.mjs.map +1 -0
- package/dist/cli.mjs +3 -2
- package/dist/{http-PMNZ42EN.mjs → http-J3IOFFIA.mjs} +8 -6
- package/dist/{import-OP7R4CYY.mjs → import-POYG5LOX.mjs} +4 -4
- package/dist/index.mjs +10 -8
- package/dist/{mcp-ABXNFUJO.mjs → mcp-7HH7UMXT.mjs} +11 -6
- package/dist/mcp-7HH7UMXT.mjs.map +1 -0
- package/dist/{stream-import-L6RJHH4L.mjs → stream-import-O3H3FGV2.mjs} +3 -3
- package/dist-web/assets/{DebugToolsPanel-DaSNc1o-.css → DebugToolsPanel-CrqULdXp.css} +1 -1
- package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-BTJxEma5.js +182 -0
- package/dist-web/assets/{EChartWordcloud-CzhfrEF_.js → EChartWordcloud-B_YisOW5.js} +1 -1
- package/dist-web/assets/{MessageExportModal-BAJKWX4y.js → MessageExportModal-C7NgEL8T.js} +1 -1
- package/dist-web/assets/{electron-CZt36wW5.js → electron-B3DFm1cC.js} +1 -1
- package/dist-web/assets/electron-BMM4Nfty.js +1 -0
- package/dist-web/assets/{fetch-qoGEVjNg.js → fetch-ArMjdMcy.js} +1 -1
- package/dist-web/assets/fetch-BFtuJaa1.js +1 -0
- package/dist-web/assets/{fetch-yWwp067l.js → fetch-BGfaAqO9.js} +1 -1
- package/dist-web/assets/{fetch-DD1EGRKV.js → fetch-BaJDB31c.js} +1 -1
- package/dist-web/assets/{fetch-JzVEwamn.js → fetch-BjDJgdN0.js} +1 -1
- package/dist-web/assets/{fetch-GMkMBzBS.js → fetch-C5CLcpQW.js} +1 -1
- package/dist-web/assets/{fetch-DXfZysDf.js → fetch-DQZvdHnG.js} +1 -1
- package/dist-web/assets/{fetch-D4p9vj1A.js → fetch-Dhfbt1BQ.js} +3 -3
- package/dist-web/assets/fetch-DnEP0uyF.js +1 -0
- package/dist-web/assets/{fetch-CgBIWyAo.js → fetch-SYrb-sZe.js} +1 -1
- package/dist-web/assets/index-CWfkrx37.js +173 -0
- package/dist-web/assets/index-D3N4NDFx.css +1 -0
- package/dist-web/assets/{index-O0PG26_v.js → index-D7_ch4zf.js} +1 -1
- package/dist-web/assets/{index-BrS_VrIY.js → index-DK9LEEzT.js} +1 -1
- package/dist-web/assets/index-DqDa_on9.js +9 -0
- package/dist-web/assets/{index-Cvlw0RLu.js → index-DrN1G9bl.js} +2 -2
- package/dist-web/assets/{index-DvWI6Yqa.js → index-MdYeovYo.js} +4 -4
- package/dist-web/assets/{vendor-nuxt-ui-C_8CsH6e.js → vendor-nuxt-ui-Zy8txNdC.js} +1 -1
- package/dist-web/assets/{vendor-reka-ui-CIMXwvEp.js → vendor-reka-ui-mMvma1EP.js} +1 -1
- package/dist-web/assets/{web-4rtrAcLu.js → web-zEXsvoZW.js} +1 -1
- package/dist-web/index.html +4 -4
- package/package.json +1 -1
- package/dist/chunk-4OMV4VNH.mjs.map +0 -1
- package/dist/chunk-CIBTUWAE.mjs.map +0 -1
- package/dist/chunk-E65ABM3C.mjs.map +0 -1
- package/dist/chunk-FSHVDWI2.mjs.map +0 -1
- package/dist/chunk-GNT5G74Z.mjs.map +0 -1
- package/dist/chunk-TCPXAX3F.mjs.map +0 -1
- package/dist/mcp-ABXNFUJO.mjs.map +0 -1
- package/dist-web/assets/DebugToolsPanel.vue_vue_type_script_setup_true_lang-BUwpIerl.js +0 -161
- package/dist-web/assets/electron-CwERrTWp.js +0 -1
- package/dist-web/assets/fetch-BxFAkm7O.js +0 -1
- package/dist-web/assets/fetch-DO8lty7_.js +0 -1
- package/dist-web/assets/index-C1t-kzfo.css +0 -1
- package/dist-web/assets/index-DABpUm3J.js +0 -9
- package/dist-web/assets/index-OsjX5hXw.js +0 -173
- /package/dist/{http-PMNZ42EN.mjs.map → http-J3IOFFIA.mjs.map} +0 -0
- /package/dist/{import-OP7R4CYY.mjs.map → import-POYG5LOX.mjs.map} +0 -0
- /package/dist/{stream-import-L6RJHH4L.mjs.map → stream-import-O3H3FGV2.mjs.map} +0 -0
|
@@ -7,33 +7,38 @@ const __dirname = __pathDirname(__filename);
|
|
|
7
7
|
import {
|
|
8
8
|
importData,
|
|
9
9
|
parseFile
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-WXC6RZCX.mjs";
|
|
11
11
|
import {
|
|
12
12
|
analyzeIncrementalImport,
|
|
13
13
|
analyzeNewImport,
|
|
14
14
|
incrementalImport,
|
|
15
15
|
streamImport
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-TC74HESZ.mjs";
|
|
17
17
|
import {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} from "./chunk-E65ABM3C.mjs";
|
|
18
|
+
assertCliDataDirCompatible
|
|
19
|
+
} from "./chunk-UB4XBM4R.mjs";
|
|
21
20
|
import {
|
|
22
21
|
getVersion
|
|
23
22
|
} from "./chunk-5ADKYYNA.mjs";
|
|
24
23
|
import {
|
|
25
|
-
|
|
24
|
+
closeServerAiLogger,
|
|
25
|
+
createCliRunAgentStream,
|
|
26
|
+
initServerAiLogger
|
|
27
|
+
} from "./chunk-ILGSSXOG.mjs";
|
|
28
|
+
import {
|
|
29
|
+
AGENT_TOOL_REGISTRY,
|
|
30
|
+
CoreDataProvider
|
|
31
|
+
} from "./chunk-IRZRIHIT.mjs";
|
|
32
|
+
import {
|
|
33
|
+
AIChatManager,
|
|
26
34
|
ALL_MIGRATIONS,
|
|
27
|
-
AgentEventHandler,
|
|
28
|
-
AiLogger,
|
|
29
35
|
AssistantManager,
|
|
30
36
|
BUILTIN_MODELS,
|
|
31
37
|
BUILTIN_PROVIDERS,
|
|
32
38
|
BUILTIN_TOOL_CATALOG,
|
|
33
|
-
CHART_CAPABILITY_CORE_TOOLS,
|
|
34
39
|
CustomModelStore,
|
|
35
40
|
CustomProviderStore,
|
|
36
|
-
|
|
41
|
+
DataDirCompatibilityError,
|
|
37
42
|
DatabaseManager,
|
|
38
43
|
LLMConfigStore,
|
|
39
44
|
MergeSessionCache,
|
|
@@ -41,24 +46,14 @@ import {
|
|
|
41
46
|
NodePathProvider,
|
|
42
47
|
POS_TAG_DEFINITIONS,
|
|
43
48
|
PreferencesManager,
|
|
44
|
-
SkillManager,
|
|
45
49
|
SkillManagerCore,
|
|
46
50
|
TempDbWriter,
|
|
47
51
|
applyPendingNodeDataDirMigrationIfNeeded,
|
|
48
|
-
applyPreprocessingPipeline,
|
|
49
|
-
batchSegmentWithFrequency,
|
|
50
52
|
buildMergedOutput,
|
|
51
53
|
buildPiModel,
|
|
52
|
-
buildSkillMenuWithBuiltinChart,
|
|
53
|
-
buildSystemPrompt,
|
|
54
|
-
checkAndCompress,
|
|
55
54
|
checkConflictsFromSources,
|
|
56
55
|
computeWordFrequency,
|
|
57
56
|
countMessagesTokens,
|
|
58
|
-
createActivateSkillTool,
|
|
59
|
-
createAiTranslate,
|
|
60
|
-
createChartSchemaGateState,
|
|
61
|
-
createCompressionLlmAdapter,
|
|
62
57
|
createDatabaseManagerAdapter,
|
|
63
58
|
createJiebaNlpProvider,
|
|
64
59
|
createNodeDataDirSwitch,
|
|
@@ -74,13 +69,9 @@ import {
|
|
|
74
69
|
fetchRemoteModels,
|
|
75
70
|
filterMessagesWithContext,
|
|
76
71
|
findEntryFileInDirectory,
|
|
77
|
-
formatAIError,
|
|
78
|
-
getAllowedBuiltinToolsForChartAutoSkill,
|
|
79
72
|
getAvailableYears,
|
|
80
73
|
getBuiltinModelsByProvider,
|
|
81
74
|
getCatchphraseAnalysis,
|
|
82
|
-
getChartCapabilitySkill,
|
|
83
|
-
getChatOverview,
|
|
84
75
|
getClusterGraph,
|
|
85
76
|
getDailyActivity,
|
|
86
77
|
getDefaultNodeUserDataDir,
|
|
@@ -104,25 +95,19 @@ import {
|
|
|
104
95
|
getSessionInfo,
|
|
105
96
|
getSessionMeta,
|
|
106
97
|
getSessionOverview,
|
|
107
|
-
getSkillConfigWithBuiltinChart,
|
|
108
98
|
getSupportedFormats,
|
|
109
99
|
getTimeRange,
|
|
110
100
|
getWeekdayActivity,
|
|
111
101
|
getYearlyActivity,
|
|
112
102
|
hasPendingElectronDataWarning,
|
|
113
103
|
initNlpDir,
|
|
114
|
-
initTokenizer,
|
|
115
104
|
isDictDownloaded,
|
|
116
105
|
isNewerStableVersion,
|
|
117
106
|
loadConfig,
|
|
118
107
|
member_service_exports,
|
|
119
108
|
mergeRulesForLocale,
|
|
120
|
-
openBetterSqliteDatabase,
|
|
121
|
-
parseAssistantFile,
|
|
122
109
|
queryMessages,
|
|
123
110
|
resolveApiKey,
|
|
124
|
-
resolveChartRuntimeForRequest,
|
|
125
|
-
runAgentCore,
|
|
126
111
|
runSimpleLlmStream,
|
|
127
112
|
scanMultiChatFile,
|
|
128
113
|
segmentText,
|
|
@@ -134,16 +119,15 @@ import {
|
|
|
134
119
|
summary_service_exports,
|
|
135
120
|
validateApiKey,
|
|
136
121
|
verifyCliDataPath,
|
|
137
|
-
wrapWithChartSchemaGate,
|
|
138
122
|
writeAuthProfile,
|
|
139
123
|
writeConfigField
|
|
140
|
-
} from "./chunk-
|
|
124
|
+
} from "./chunk-QY67NN65.mjs";
|
|
141
125
|
import {
|
|
142
126
|
resolveCliPath
|
|
143
127
|
} from "./chunk-FJ35V3TE.mjs";
|
|
144
128
|
|
|
145
129
|
// src/http/index.ts
|
|
146
|
-
import * as
|
|
130
|
+
import * as fs9 from "fs";
|
|
147
131
|
import * as crypto4 from "crypto";
|
|
148
132
|
|
|
149
133
|
// src/http/server.ts
|
|
@@ -159,6 +143,7 @@ var HTTP_STATUS = {
|
|
|
159
143
|
["SQL_EXECUTION_ERROR" /* SQL_EXECUTION_ERROR */]: 400,
|
|
160
144
|
["EXPORT_TOO_LARGE" /* EXPORT_TOO_LARGE */]: 400,
|
|
161
145
|
["BODY_TOO_LARGE" /* BODY_TOO_LARGE */]: 413,
|
|
146
|
+
["DATA_DIR_INCOMPATIBLE" /* DATA_DIR_INCOMPATIBLE */]: 409,
|
|
162
147
|
["SERVER_ERROR" /* SERVER_ERROR */]: 500
|
|
163
148
|
};
|
|
164
149
|
var ApiError = class extends Error {
|
|
@@ -189,6 +174,14 @@ function exportTooLarge(count, limit) {
|
|
|
189
174
|
function serverError(message = "Internal server error") {
|
|
190
175
|
return new ApiError("SERVER_ERROR" /* SERVER_ERROR */, message);
|
|
191
176
|
}
|
|
177
|
+
function dataDirIncompatible(message) {
|
|
178
|
+
return new ApiError("DATA_DIR_INCOMPATIBLE" /* DATA_DIR_INCOMPATIBLE */, message);
|
|
179
|
+
}
|
|
180
|
+
function apiErrorFromUnknown(error) {
|
|
181
|
+
if (error instanceof ApiError) return error;
|
|
182
|
+
if (error instanceof DataDirCompatibilityError) return dataDirIncompatible(error.message);
|
|
183
|
+
return null;
|
|
184
|
+
}
|
|
192
185
|
function successResponse(data, meta) {
|
|
193
186
|
return {
|
|
194
187
|
success: true,
|
|
@@ -799,7 +792,7 @@ function registerExportRoutes(server2, ctx) {
|
|
|
799
792
|
timeFilter: body.timeFilter,
|
|
800
793
|
senderIds: body.senderIds,
|
|
801
794
|
contextSize: body.contextSize,
|
|
802
|
-
|
|
795
|
+
segmentIds: body.segmentIds
|
|
803
796
|
});
|
|
804
797
|
if (!result.success) {
|
|
805
798
|
return reply.code(500).send({ error: result.error });
|
|
@@ -1181,10 +1174,10 @@ function registerAiFilterRoutes(server2, ctx) {
|
|
|
1181
1174
|
return filterMessagesWithContext(db, { keywords, timeFilter, senderIds, contextSize, page, pageSize });
|
|
1182
1175
|
});
|
|
1183
1176
|
server2.post("/_web/ai/multiple-sessions-messages", async (request, reply) => {
|
|
1184
|
-
const { sessionId,
|
|
1177
|
+
const { sessionId, segmentIds, page, pageSize } = request.body;
|
|
1185
1178
|
const db = ctx.dbManager.open(sessionId);
|
|
1186
1179
|
if (!db) return reply.code(404).send({ error: `Session not found: ${sessionId}` });
|
|
1187
|
-
return getMultipleSessionsMessages(db,
|
|
1180
|
+
return getMultipleSessionsMessages(db, segmentIds, page, pageSize);
|
|
1188
1181
|
});
|
|
1189
1182
|
}
|
|
1190
1183
|
|
|
@@ -1263,31 +1256,31 @@ function registerAiToolRoutes(server2, ctx) {
|
|
|
1263
1256
|
});
|
|
1264
1257
|
}
|
|
1265
1258
|
|
|
1266
|
-
// ../../packages/http-routes/src/routes/web/ai-
|
|
1267
|
-
function
|
|
1268
|
-
const cm = ctx.
|
|
1259
|
+
// ../../packages/http-routes/src/routes/web/ai-chats.ts
|
|
1260
|
+
function registerAiChatRoutes(server2, ctx) {
|
|
1261
|
+
const cm = ctx.aiChatManager;
|
|
1269
1262
|
if (!cm) return;
|
|
1270
|
-
server2.post("/_web/ai/
|
|
1263
|
+
server2.post("/_web/ai/chats", async (request) => {
|
|
1271
1264
|
const { sessionId, title, assistantId } = request.body;
|
|
1272
|
-
return cm.
|
|
1265
|
+
return cm.createAIChat(sessionId, title, assistantId);
|
|
1273
1266
|
});
|
|
1274
|
-
server2.get("/_web/ai/
|
|
1267
|
+
server2.get("/_web/ai/chats", async (request) => {
|
|
1275
1268
|
const { sessionId } = request.query;
|
|
1276
1269
|
if (!sessionId) return [];
|
|
1277
|
-
return cm.
|
|
1270
|
+
return cm.getAIChats(sessionId);
|
|
1278
1271
|
});
|
|
1279
|
-
server2.get("/_web/ai/
|
|
1280
|
-
const conv = cm.
|
|
1281
|
-
if (!conv) return reply.code(404).send({ error: "
|
|
1272
|
+
server2.get("/_web/ai/chats/:id", async (request, reply) => {
|
|
1273
|
+
const conv = cm.getAIChat(request.params.id);
|
|
1274
|
+
if (!conv) return reply.code(404).send({ error: "AI chat not found" });
|
|
1282
1275
|
return conv;
|
|
1283
1276
|
});
|
|
1284
|
-
server2.put("/_web/ai/
|
|
1285
|
-
return cm.
|
|
1277
|
+
server2.put("/_web/ai/chats/:id/title", async (request) => {
|
|
1278
|
+
return cm.updateAIChatTitle(request.params.id, request.body.title);
|
|
1286
1279
|
});
|
|
1287
|
-
server2.delete("/_web/ai/
|
|
1288
|
-
return cm.
|
|
1280
|
+
server2.delete("/_web/ai/chats/:id", async (request) => {
|
|
1281
|
+
return cm.deleteAIChat(request.params.id);
|
|
1289
1282
|
});
|
|
1290
|
-
server2.post("/_web/ai/
|
|
1283
|
+
server2.post("/_web/ai/chats/:id/messages", async (request) => {
|
|
1291
1284
|
const { role, content, dataKeywords, dataMessageCount, contentBlocks, tokenUsage } = request.body;
|
|
1292
1285
|
return cm.addMessage(
|
|
1293
1286
|
request.params.id,
|
|
@@ -1299,23 +1292,23 @@ function registerAiConversationRoutes(server2, ctx) {
|
|
|
1299
1292
|
tokenUsage
|
|
1300
1293
|
);
|
|
1301
1294
|
});
|
|
1302
|
-
server2.get("/_web/ai/
|
|
1295
|
+
server2.get("/_web/ai/chats/:id/messages", async (request) => {
|
|
1303
1296
|
return cm.getMessages(request.params.id);
|
|
1304
1297
|
});
|
|
1305
|
-
server2.post("/_web/ai/
|
|
1298
|
+
server2.post("/_web/ai/chats/:id/messages/:messageId/delete-from", async (request, reply) => {
|
|
1306
1299
|
const { id, messageId } = request.params;
|
|
1307
1300
|
if (!id || typeof id !== "string" || !messageId || typeof messageId !== "string") {
|
|
1308
|
-
return reply.code(400).send({ error: "
|
|
1301
|
+
return reply.code(400).send({ error: "aiChatId and messageId are required" });
|
|
1309
1302
|
}
|
|
1310
1303
|
cm.deleteMessagesFrom(id, messageId);
|
|
1311
1304
|
return { success: true };
|
|
1312
1305
|
});
|
|
1313
|
-
server2.post("/_web/ai/
|
|
1306
|
+
server2.post("/_web/ai/chats/:id/fork", async (request, reply) => {
|
|
1314
1307
|
const { upToMessageId, title } = request.body;
|
|
1315
1308
|
if (!upToMessageId || typeof upToMessageId !== "string") {
|
|
1316
1309
|
return reply.code(400).send({ error: "upToMessageId is required" });
|
|
1317
1310
|
}
|
|
1318
|
-
return cm.
|
|
1311
|
+
return cm.forkAIChat(request.params.id, upToMessageId, title);
|
|
1319
1312
|
});
|
|
1320
1313
|
server2.put("/_web/ai/messages/:messageId/content", async (request, reply) => {
|
|
1321
1314
|
const { content } = request.body;
|
|
@@ -1325,23 +1318,23 @@ function registerAiConversationRoutes(server2, ctx) {
|
|
|
1325
1318
|
cm.updateMessageContent(request.params.messageId, content);
|
|
1326
1319
|
return { success: true };
|
|
1327
1320
|
});
|
|
1328
|
-
server2.post("/_web/ai/
|
|
1321
|
+
server2.post("/_web/ai/chats/:id/messages/:messageId/delete-relink", async (request, reply) => {
|
|
1329
1322
|
const { id, messageId } = request.params;
|
|
1330
1323
|
if (!id || !messageId) {
|
|
1331
|
-
return reply.code(400).send({ error: "
|
|
1324
|
+
return reply.code(400).send({ error: "aiChatId and messageId are required" });
|
|
1332
1325
|
}
|
|
1333
1326
|
cm.deleteAndRelinkMessage(id, messageId);
|
|
1334
1327
|
return { success: true };
|
|
1335
1328
|
});
|
|
1336
|
-
server2.post("/_web/ai/
|
|
1329
|
+
server2.post("/_web/ai/chats/:id/messages/insert-after", async (request, reply) => {
|
|
1337
1330
|
const { afterMessageId, role, content, contentBlocks, tokenUsage } = request.body;
|
|
1338
1331
|
if (!afterMessageId || typeof afterMessageId !== "string") {
|
|
1339
1332
|
return reply.code(400).send({ error: "afterMessageId is required" });
|
|
1340
1333
|
}
|
|
1341
1334
|
return cm.insertMessageAfter(request.params.id, afterMessageId, role, content, contentBlocks, tokenUsage);
|
|
1342
1335
|
});
|
|
1343
|
-
server2.get("/_web/ai/
|
|
1344
|
-
return cm.
|
|
1336
|
+
server2.get("/_web/ai/chats/:id/token-usage", async (request) => {
|
|
1337
|
+
return cm.getAIChatTokenUsage(request.params.id);
|
|
1345
1338
|
});
|
|
1346
1339
|
server2.get("/_web/ai/debug/schema", async () => {
|
|
1347
1340
|
return cm.getAiSchema();
|
|
@@ -1362,7 +1355,7 @@ function registerAiConversationRoutes(server2, ctx) {
|
|
|
1362
1355
|
const cleared = cm.clearAllDebugContext();
|
|
1363
1356
|
return { success: true, cleared };
|
|
1364
1357
|
});
|
|
1365
|
-
server2.get("/_web/ai/
|
|
1358
|
+
server2.get("/_web/ai/chats/:id/estimate-tokens", async (request) => {
|
|
1366
1359
|
const history = cm.getHistoryForAgent(request.params.id);
|
|
1367
1360
|
const tokens = countMessagesTokens(history.map((m) => ({ role: m.role, content: m.content })));
|
|
1368
1361
|
return { success: true, tokens, messageCount: history.length };
|
|
@@ -1389,8 +1382,8 @@ function registerAiSummaryRoutes(server2, ctx) {
|
|
|
1389
1382
|
if (!deps) return;
|
|
1390
1383
|
const { sessionAdapter: adapter } = ctx;
|
|
1391
1384
|
server2.post("/_web/sessions/:id/summaries/generate", async (request, reply) => {
|
|
1392
|
-
const {
|
|
1393
|
-
const result = await summary_service_exports.generateSummary(adapter, request.params.id,
|
|
1385
|
+
const { segmentId, locale, forceRegenerate, strategy } = request.body;
|
|
1386
|
+
const result = await summary_service_exports.generateSummary(adapter, request.params.id, segmentId, deps, {
|
|
1394
1387
|
locale,
|
|
1395
1388
|
forceRegenerate,
|
|
1396
1389
|
strategy
|
|
@@ -1412,8 +1405,8 @@ function registerAiSummaryRoutes(server2, ctx) {
|
|
|
1412
1405
|
return result;
|
|
1413
1406
|
});
|
|
1414
1407
|
server2.post("/_web/sessions/:id/summaries/check-can-generate", async (request) => {
|
|
1415
|
-
const {
|
|
1416
|
-
return summary_service_exports.checkCanGenerate(adapter, request.params.id,
|
|
1408
|
+
const { segmentIds } = request.body;
|
|
1409
|
+
return summary_service_exports.checkCanGenerate(adapter, request.params.id, segmentIds);
|
|
1417
1410
|
});
|
|
1418
1411
|
}
|
|
1419
1412
|
|
|
@@ -1853,7 +1846,7 @@ function registerSharedRoutes(server2, ctx, options) {
|
|
|
1853
1846
|
if (options?.requireAi) {
|
|
1854
1847
|
const missing = [];
|
|
1855
1848
|
if (!ctx.aiDataDir) missing.push("aiDataDir");
|
|
1856
|
-
if (!ctx.
|
|
1849
|
+
if (!ctx.aiChatManager) missing.push("aiChatManager");
|
|
1857
1850
|
if (!ctx.assistantManager) missing.push("assistantManager");
|
|
1858
1851
|
if (!ctx.skillManagerCore) missing.push("skillManagerCore");
|
|
1859
1852
|
if (!ctx.llmConfigStore) missing.push("llmConfigStore");
|
|
@@ -1871,7 +1864,7 @@ function registerSharedRoutes(server2, ctx, options) {
|
|
|
1871
1864
|
registerAiAgentStreamRoutes(server2, ctx);
|
|
1872
1865
|
registerAiFilterRoutes(server2, ctx);
|
|
1873
1866
|
registerAiToolRoutes(server2, ctx);
|
|
1874
|
-
|
|
1867
|
+
registerAiChatRoutes(server2, ctx);
|
|
1875
1868
|
registerAiSummaryRoutes(server2, ctx);
|
|
1876
1869
|
registerMergeRoutes(server2, ctx);
|
|
1877
1870
|
registerCacheRoutes(server2, ctx);
|
|
@@ -1929,8 +1922,9 @@ function createServer() {
|
|
|
1929
1922
|
});
|
|
1930
1923
|
server2.addHook("onRequest", authHook);
|
|
1931
1924
|
server2.setErrorHandler((error, _request, reply) => {
|
|
1932
|
-
|
|
1933
|
-
|
|
1925
|
+
const apiError = apiErrorFromUnknown(error);
|
|
1926
|
+
if (apiError) {
|
|
1927
|
+
reply.code(apiError.statusCode).send(errorResponse(apiError));
|
|
1934
1928
|
return;
|
|
1935
1929
|
}
|
|
1936
1930
|
if (error.statusCode === 413) {
|
|
@@ -2346,7 +2340,7 @@ function registerWebRoutes(server2, dbManager2, options) {
|
|
|
2346
2340
|
const resolvedPathProvider = options?.pathProvider ?? fallbackPathProvider;
|
|
2347
2341
|
const ai = options?.aiContext;
|
|
2348
2342
|
const cliStreamImport = async (dm, filePath) => {
|
|
2349
|
-
const { streamImport: streamImport2 } = await import("./stream-import-
|
|
2343
|
+
const { streamImport: streamImport2 } = await import("./stream-import-O3H3FGV2.mjs");
|
|
2350
2344
|
const result = await streamImport2(dm, filePath);
|
|
2351
2345
|
if (!result.sessionId) throw new Error("Import succeeded but no sessionId returned");
|
|
2352
2346
|
return { sessionId: result.sessionId };
|
|
@@ -2382,7 +2376,7 @@ function registerWebRoutes(server2, dbManager2, options) {
|
|
|
2382
2376
|
},
|
|
2383
2377
|
...ai && {
|
|
2384
2378
|
aiDataDir: ai.aiDataDir,
|
|
2385
|
-
|
|
2379
|
+
aiChatManager: ai.aiChatManager,
|
|
2386
2380
|
assistantManager: ai.assistantManager,
|
|
2387
2381
|
skillManagerCore: ai.skillManagerCore,
|
|
2388
2382
|
llmConfigStore: ai.llmConfigStore,
|
|
@@ -2442,24 +2436,6 @@ function registerProxyRoutes(server2) {
|
|
|
2442
2436
|
});
|
|
2443
2437
|
}
|
|
2444
2438
|
|
|
2445
|
-
// src/ai/logger.ts
|
|
2446
|
-
var logger = null;
|
|
2447
|
-
function initServerAiLogger(logsDir) {
|
|
2448
|
-
if (!logger) {
|
|
2449
|
-
logger = new AiLogger(logsDir);
|
|
2450
|
-
}
|
|
2451
|
-
return logger;
|
|
2452
|
-
}
|
|
2453
|
-
function getServerAiLogger() {
|
|
2454
|
-
return logger;
|
|
2455
|
-
}
|
|
2456
|
-
function closeServerAiLogger() {
|
|
2457
|
-
if (logger) {
|
|
2458
|
-
logger.close();
|
|
2459
|
-
logger = null;
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
|
-
|
|
2463
2439
|
// src/ai/manager-factory.ts
|
|
2464
2440
|
import * as fs5 from "fs";
|
|
2465
2441
|
import * as path7 from "path";
|
|
@@ -2519,435 +2495,14 @@ function getSkillManagerCore(aiDataDir) {
|
|
|
2519
2495
|
return cached.skill;
|
|
2520
2496
|
}
|
|
2521
2497
|
|
|
2522
|
-
// src/ai/tool-adapter.ts
|
|
2523
|
-
var DEFAULT_MAX_TOOL_RESULT_TOKENS = 8e3;
|
|
2524
|
-
var TOOL_TRUNCATION_STRATEGY = {
|
|
2525
|
-
search_messages: "keep_first",
|
|
2526
|
-
deep_search_messages: "keep_first",
|
|
2527
|
-
get_recent_messages: "keep_last",
|
|
2528
|
-
get_message_context: "keep_last",
|
|
2529
|
-
get_session_messages: "keep_last",
|
|
2530
|
-
get_conversation_between: "keep_last"
|
|
2531
|
-
};
|
|
2532
|
-
function convertJsonSchemaToParameters(schema) {
|
|
2533
|
-
const properties = {};
|
|
2534
|
-
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
2535
|
-
properties[key] = { ...prop };
|
|
2536
|
-
}
|
|
2537
|
-
return {
|
|
2538
|
-
type: "object",
|
|
2539
|
-
properties,
|
|
2540
|
-
required: schema.required || []
|
|
2541
|
-
};
|
|
2542
|
-
}
|
|
2543
|
-
function adaptToolsForAgent(tools, getContext, options) {
|
|
2544
|
-
const tokenBudget = options?.maxToolResultTokens ?? DEFAULT_MAX_TOOL_RESULT_TOKENS;
|
|
2545
|
-
const chartSchemaGateState = createChartSchemaGateState();
|
|
2546
|
-
return tools.map(
|
|
2547
|
-
(tool) => wrapWithChartSchemaGate(
|
|
2548
|
-
{
|
|
2549
|
-
name: tool.name,
|
|
2550
|
-
label: tool.name,
|
|
2551
|
-
description: tool.description,
|
|
2552
|
-
parameters: convertJsonSchemaToParameters(tool.inputSchema),
|
|
2553
|
-
async execute(_toolCallId, params) {
|
|
2554
|
-
const toolParams = params && typeof params === "object" ? params : {};
|
|
2555
|
-
const ctx = getContext();
|
|
2556
|
-
const execCtx = {
|
|
2557
|
-
db: ctx.db,
|
|
2558
|
-
dataProvider: new CoreDataProvider(ctx.db),
|
|
2559
|
-
sessionId: ctx.sessionId,
|
|
2560
|
-
locale: ctx.locale,
|
|
2561
|
-
segmentText: (texts, locale, options2) => batchSegmentWithFrequency(texts, locale, options2)
|
|
2562
|
-
};
|
|
2563
|
-
try {
|
|
2564
|
-
const result = await tool.handler(toolParams, execCtx);
|
|
2565
|
-
const chartDetails = result.chart || result.charts ? {
|
|
2566
|
-
...result.chart ? { chart: result.chart } : {},
|
|
2567
|
-
...result.charts ? { charts: result.charts } : {}
|
|
2568
|
-
} : {};
|
|
2569
|
-
if (result.rawMessages && result.rawMessages.length > 0) {
|
|
2570
|
-
const pipelineResult = applyPreprocessingPipeline({
|
|
2571
|
-
rawMessages: result.rawMessages,
|
|
2572
|
-
locale: ctx.locale,
|
|
2573
|
-
maxToolResultTokens: tokenBudget,
|
|
2574
|
-
truncationStrategy: TOOL_TRUNCATION_STRATEGY[tool.name] ?? "keep_last",
|
|
2575
|
-
extraDetails: result.data ?? {},
|
|
2576
|
-
logger: getServerAiLogger() ?? void 0
|
|
2577
|
-
});
|
|
2578
|
-
return {
|
|
2579
|
-
content: [{ type: "text", text: pipelineResult.text }],
|
|
2580
|
-
details: Object.keys(chartDetails).length > 0 ? chartDetails : null
|
|
2581
|
-
};
|
|
2582
|
-
}
|
|
2583
|
-
const baseDetails = typeof result.data === "object" && result.data !== null ? result.data : result.data === void 0 ? null : { value: result.data };
|
|
2584
|
-
return {
|
|
2585
|
-
content: [{ type: "text", text: result.content }],
|
|
2586
|
-
details: Object.keys(chartDetails).length > 0 ? { ...baseDetails ?? {}, ...chartDetails } : baseDetails
|
|
2587
|
-
};
|
|
2588
|
-
} catch (error) {
|
|
2589
|
-
const msg = error instanceof Error ? error.message : String(error);
|
|
2590
|
-
return { content: [{ type: "text", text: `Error: ${msg}` }], details: null };
|
|
2591
|
-
}
|
|
2592
|
-
}
|
|
2593
|
-
},
|
|
2594
|
-
chartSchemaGateState
|
|
2595
|
-
)
|
|
2596
|
-
);
|
|
2597
|
-
}
|
|
2598
|
-
|
|
2599
|
-
// src/ai/llm-config.ts
|
|
2600
|
-
import * as fs6 from "fs";
|
|
2601
|
-
import * as path8 from "path";
|
|
2602
|
-
function loadLlmConfig(aiDataDir) {
|
|
2603
|
-
const configPath = path8.join(aiDataDir, "llm-config.json");
|
|
2604
|
-
if (!fs6.existsSync(configPath)) {
|
|
2605
|
-
return { configs: [], defaultAssistant: null, fastModel: null };
|
|
2606
|
-
}
|
|
2607
|
-
try {
|
|
2608
|
-
const data = JSON.parse(fs6.readFileSync(configPath, "utf-8"));
|
|
2609
|
-
const configs = (data.configs || []).map((c) => {
|
|
2610
|
-
const provider = c.provider || "";
|
|
2611
|
-
const authProfile = c.authProfile;
|
|
2612
|
-
const profileKey = resolveApiKey(provider, authProfile);
|
|
2613
|
-
const rawKey = c.apiKey || "";
|
|
2614
|
-
const fallbackKey = rawKey.startsWith("enc:") ? "" : rawKey;
|
|
2615
|
-
return {
|
|
2616
|
-
...c,
|
|
2617
|
-
apiKey: profileKey || fallbackKey
|
|
2618
|
-
};
|
|
2619
|
-
});
|
|
2620
|
-
return {
|
|
2621
|
-
configs,
|
|
2622
|
-
defaultAssistant: data.defaultAssistant ?? null,
|
|
2623
|
-
fastModel: data.fastModel ?? null
|
|
2624
|
-
};
|
|
2625
|
-
} catch {
|
|
2626
|
-
return { configs: [], defaultAssistant: null, fastModel: null };
|
|
2627
|
-
}
|
|
2628
|
-
}
|
|
2629
|
-
function resolveSlot(slot, configs) {
|
|
2630
|
-
if (slot && configs.some((c) => c.id === slot.configId)) return slot;
|
|
2631
|
-
const fallback = configs[0];
|
|
2632
|
-
if (!fallback) return null;
|
|
2633
|
-
return { configId: fallback.id, modelId: fallback.model };
|
|
2634
|
-
}
|
|
2635
|
-
function getDefaultAssistantConfig(aiDataDir) {
|
|
2636
|
-
const store = loadLlmConfig(aiDataDir);
|
|
2637
|
-
const slot = resolveSlot(store.defaultAssistant, store.configs);
|
|
2638
|
-
if (!slot) return null;
|
|
2639
|
-
const config = store.configs.find((c) => c.id === slot.configId);
|
|
2640
|
-
if (!config) return null;
|
|
2641
|
-
return { ...config, model: slot.modelId || config.model };
|
|
2642
|
-
}
|
|
2643
|
-
function buildPiModel2(config) {
|
|
2644
|
-
return buildPiModel(config);
|
|
2645
|
-
}
|
|
2646
|
-
|
|
2647
|
-
// src/ai/assistant-loader.ts
|
|
2648
|
-
import * as fs7 from "fs";
|
|
2649
|
-
import * as path9 from "path";
|
|
2650
|
-
function loadAssistantConfig(aiDataDir, assistantId) {
|
|
2651
|
-
const filePath = path9.join(aiDataDir, "assistants", `${assistantId}.md`);
|
|
2652
|
-
if (!fs7.existsSync(filePath)) return null;
|
|
2653
|
-
try {
|
|
2654
|
-
const content = fs7.readFileSync(filePath, "utf-8");
|
|
2655
|
-
return parseAssistantFile(content, filePath);
|
|
2656
|
-
} catch {
|
|
2657
|
-
return null;
|
|
2658
|
-
}
|
|
2659
|
-
}
|
|
2660
|
-
|
|
2661
|
-
// src/ai/agent.ts
|
|
2662
|
-
async function runServerAgent(options) {
|
|
2663
|
-
const {
|
|
2664
|
-
userMessage,
|
|
2665
|
-
conversationId,
|
|
2666
|
-
historyLeafMessageId,
|
|
2667
|
-
chatType = "group",
|
|
2668
|
-
locale = "zh-CN",
|
|
2669
|
-
assistantSystemPrompt,
|
|
2670
|
-
skillMenu,
|
|
2671
|
-
skillDef,
|
|
2672
|
-
compressionConfig,
|
|
2673
|
-
tools = [],
|
|
2674
|
-
aiDataDir,
|
|
2675
|
-
convManager: convManager2,
|
|
2676
|
-
onEvent,
|
|
2677
|
-
abortSignal,
|
|
2678
|
-
ownerInfo,
|
|
2679
|
-
mentionedMembers,
|
|
2680
|
-
dataSnapshot,
|
|
2681
|
-
thinkingLevel
|
|
2682
|
-
} = options;
|
|
2683
|
-
const aiLogger = getServerAiLogger();
|
|
2684
|
-
await initTokenizer();
|
|
2685
|
-
const llmConfig = getDefaultAssistantConfig(aiDataDir);
|
|
2686
|
-
if (!llmConfig) {
|
|
2687
|
-
onEvent({ type: "error", error: { name: "ConfigError", message: "LLM service not configured" } });
|
|
2688
|
-
onEvent({ type: "done", isFinished: true });
|
|
2689
|
-
return;
|
|
2690
|
-
}
|
|
2691
|
-
const piModel = buildPiModel2(llmConfig);
|
|
2692
|
-
const t = createAiTranslate(locale);
|
|
2693
|
-
let skillCtx;
|
|
2694
|
-
if (skillDef) {
|
|
2695
|
-
skillCtx = { skillDef };
|
|
2696
|
-
} else if (skillMenu) {
|
|
2697
|
-
skillCtx = { skillMenu };
|
|
2698
|
-
}
|
|
2699
|
-
const systemPrompt = buildSystemPrompt({
|
|
2700
|
-
t,
|
|
2701
|
-
chatType,
|
|
2702
|
-
assistantSystemPrompt,
|
|
2703
|
-
ownerInfo,
|
|
2704
|
-
locale,
|
|
2705
|
-
skillCtx,
|
|
2706
|
-
mentionedMembers,
|
|
2707
|
-
dataSnapshot
|
|
2708
|
-
});
|
|
2709
|
-
const handler = new AgentEventHandler({
|
|
2710
|
-
onChunk: onEvent,
|
|
2711
|
-
context: {},
|
|
2712
|
-
systemPrompt
|
|
2713
|
-
});
|
|
2714
|
-
if (compressionConfig?.enabled && historyLeafMessageId === void 0) {
|
|
2715
|
-
const llmAdapter = createCompressionLlmAdapter({
|
|
2716
|
-
piModel,
|
|
2717
|
-
apiKey: llmConfig.apiKey,
|
|
2718
|
-
onCompressing: () => handler.emitStatus("compressing", [])
|
|
2719
|
-
});
|
|
2720
|
-
const compressionResult = await checkAndCompress(
|
|
2721
|
-
conversationId,
|
|
2722
|
-
compressionConfig,
|
|
2723
|
-
systemPrompt,
|
|
2724
|
-
llmAdapter,
|
|
2725
|
-
convManager2,
|
|
2726
|
-
aiLogger ?? void 0
|
|
2727
|
-
);
|
|
2728
|
-
if (compressionResult.compressed) {
|
|
2729
|
-
onEvent({
|
|
2730
|
-
type: "compression_done",
|
|
2731
|
-
compressionResult: {
|
|
2732
|
-
summaryContent: compressionResult.summaryContent ?? "",
|
|
2733
|
-
tokensBefore: compressionResult.tokensBefore ?? 0,
|
|
2734
|
-
tokensAfter: compressionResult.tokensAfter ?? 0,
|
|
2735
|
-
timestamp: Date.now()
|
|
2736
|
-
}
|
|
2737
|
-
});
|
|
2738
|
-
}
|
|
2739
|
-
} else if (compressionConfig?.enabled && historyLeafMessageId !== void 0) {
|
|
2740
|
-
aiLogger?.info?.("Compression", "Skipping compression for edited branch request", {
|
|
2741
|
-
conversationId,
|
|
2742
|
-
historyLeafMessageId
|
|
2743
|
-
});
|
|
2744
|
-
}
|
|
2745
|
-
if (abortSignal?.aborted) {
|
|
2746
|
-
handler.emitStatus("aborted", [], { force: true });
|
|
2747
|
-
onEvent({ type: "done", isFinished: true, usage: handler.cloneUsage() });
|
|
2748
|
-
return;
|
|
2749
|
-
}
|
|
2750
|
-
let history = [];
|
|
2751
|
-
try {
|
|
2752
|
-
history = convManager2.getHistoryForAgent(conversationId, void 0, historyLeafMessageId);
|
|
2753
|
-
} catch {
|
|
2754
|
-
}
|
|
2755
|
-
handler.emitStatus("preparing", [], { pendingUserMessage: userMessage, force: true });
|
|
2756
|
-
const steerMessage = t("ai.agent.answerWithoutTools");
|
|
2757
|
-
let cachedMessages = [];
|
|
2758
|
-
try {
|
|
2759
|
-
const result = await runAgentCore({
|
|
2760
|
-
piModel,
|
|
2761
|
-
apiKey: llmConfig.apiKey,
|
|
2762
|
-
systemPrompt,
|
|
2763
|
-
tools,
|
|
2764
|
-
history,
|
|
2765
|
-
userMessage,
|
|
2766
|
-
maxToolRounds: DEFAULT_MAX_TOOL_ROUNDS,
|
|
2767
|
-
abortSignal,
|
|
2768
|
-
steerMessage,
|
|
2769
|
-
thinkingLevel,
|
|
2770
|
-
onConvertToLlm: (filteredMessages) => {
|
|
2771
|
-
cachedMessages = filteredMessages;
|
|
2772
|
-
},
|
|
2773
|
-
onEvent: (coreEvent) => handler.handleCoreEvent(coreEvent, cachedMessages),
|
|
2774
|
-
onDebugContext: (messages) => {
|
|
2775
|
-
try {
|
|
2776
|
-
convManager2.setPendingDebugContext(conversationId, JSON.stringify(messages, null, 2));
|
|
2777
|
-
} catch {
|
|
2778
|
-
}
|
|
2779
|
-
}
|
|
2780
|
-
});
|
|
2781
|
-
if (result.error) {
|
|
2782
|
-
const friendlyMessage = formatAIError(result.error);
|
|
2783
|
-
onEvent({ type: "error", error: { name: "AgentError", message: friendlyMessage } });
|
|
2784
|
-
}
|
|
2785
|
-
handler.emitStatus("completed", cachedMessages, { force: true });
|
|
2786
|
-
onEvent({ type: "done", isFinished: true, usage: result.usage });
|
|
2787
|
-
} catch (error) {
|
|
2788
|
-
const friendlyMessage = formatAIError(error);
|
|
2789
|
-
aiLogger?.error("ServerAgent", "Agent execution error", { error: String(error) });
|
|
2790
|
-
handler.emitStatus("error", cachedMessages, { force: true });
|
|
2791
|
-
onEvent({ type: "error", error: { name: "AgentError", message: friendlyMessage } });
|
|
2792
|
-
onEvent({ type: "done", isFinished: true, usage: handler.cloneUsage() });
|
|
2793
|
-
}
|
|
2794
|
-
}
|
|
2795
|
-
|
|
2796
|
-
// src/ai/agent-stream-runner.ts
|
|
2797
|
-
function getAiDir(dbManager2) {
|
|
2798
|
-
const pathProvider = dbManager2["pathProvider"];
|
|
2799
|
-
if (!pathProvider) {
|
|
2800
|
-
throw Object.assign(new Error("PathProvider not available"), { statusCode: 500 });
|
|
2801
|
-
}
|
|
2802
|
-
return pathProvider.getAiDataDir();
|
|
2803
|
-
}
|
|
2804
|
-
var RAW_SQL_TOOL_NAMES = /* @__PURE__ */ new Set(["execute_sql"]);
|
|
2805
|
-
function getAvailableToolDefs(isChartCapability, allowedToolSet) {
|
|
2806
|
-
if (isChartCapability) {
|
|
2807
|
-
const chartCoreTools = new Set(CHART_CAPABILITY_CORE_TOOLS);
|
|
2808
|
-
return AGENT_TOOL_REGISTRY.filter(
|
|
2809
|
-
(tool) => chartCoreTools.has(tool.name) || tool.category === "analysis" && allowedToolSet?.has(tool.name) && !RAW_SQL_TOOL_NAMES.has(tool.name)
|
|
2810
|
-
);
|
|
2811
|
-
}
|
|
2812
|
-
return allowedToolSet ? AGENT_TOOL_REGISTRY.filter((tool) => tool.category !== "analysis" || allowedToolSet.has(tool.name)) : AGENT_TOOL_REGISTRY;
|
|
2813
|
-
}
|
|
2814
|
-
function getAllowedToolSet(isChartCapability, allowedBuiltinTools) {
|
|
2815
|
-
if (isChartCapability) {
|
|
2816
|
-
return new Set(allowedBuiltinTools);
|
|
2817
|
-
}
|
|
2818
|
-
return allowedBuiltinTools === void 0 ? null : new Set(allowedBuiltinTools);
|
|
2819
|
-
}
|
|
2820
|
-
function createCliRunAgentStream(dbManager2, convManager2) {
|
|
2821
|
-
return async (params, onEvent, abortSignal) => {
|
|
2822
|
-
const {
|
|
2823
|
-
userMessage,
|
|
2824
|
-
conversationId,
|
|
2825
|
-
historyLeafMessageId,
|
|
2826
|
-
sessionId,
|
|
2827
|
-
chatType,
|
|
2828
|
-
locale,
|
|
2829
|
-
assistantId,
|
|
2830
|
-
skillId,
|
|
2831
|
-
enableAutoSkill,
|
|
2832
|
-
compressionConfig,
|
|
2833
|
-
ownerInfo,
|
|
2834
|
-
mentionedMembers,
|
|
2835
|
-
thinkingLevel
|
|
2836
|
-
} = params;
|
|
2837
|
-
const aiDataDir = getAiDir(dbManager2);
|
|
2838
|
-
let assistantSystemPrompt;
|
|
2839
|
-
let assistantAllowedTools;
|
|
2840
|
-
if (assistantId) {
|
|
2841
|
-
const assistantConfig = loadAssistantConfig(aiDataDir, assistantId);
|
|
2842
|
-
if (assistantConfig?.systemPrompt) {
|
|
2843
|
-
assistantSystemPrompt = assistantConfig.systemPrompt;
|
|
2844
|
-
}
|
|
2845
|
-
assistantAllowedTools = assistantConfig?.allowedBuiltinTools;
|
|
2846
|
-
}
|
|
2847
|
-
const llmConfig = getDefaultAssistantConfig(aiDataDir);
|
|
2848
|
-
const maxToolResultPercent = compressionConfig?.maxToolResultPercent ?? 50;
|
|
2849
|
-
const contextWindow = llmConfig ? buildPiModel2(llmConfig).contextWindow ?? 128e3 : 128e3;
|
|
2850
|
-
const maxToolResultTokens = Math.floor(contextWindow * (maxToolResultPercent / 100));
|
|
2851
|
-
const db = dbManager2.open?.(sessionId);
|
|
2852
|
-
const chartRuntime = resolveChartRuntimeForRequest({
|
|
2853
|
-
skillId,
|
|
2854
|
-
userMessage,
|
|
2855
|
-
locale,
|
|
2856
|
-
assistantAllowedTools
|
|
2857
|
-
});
|
|
2858
|
-
const isChartCapability = chartRuntime.isChartCapability;
|
|
2859
|
-
const autoSkillAllowedTools = !skillId && enableAutoSkill ? getAllowedBuiltinToolsForChartAutoSkill(assistantAllowedTools) : assistantAllowedTools;
|
|
2860
|
-
const allowedToolSet = getAllowedToolSet(
|
|
2861
|
-
isChartCapability,
|
|
2862
|
-
isChartCapability ? chartRuntime.allowedBuiltinTools : autoSkillAllowedTools
|
|
2863
|
-
);
|
|
2864
|
-
const availableToolDefs = getAvailableToolDefs(isChartCapability, allowedToolSet);
|
|
2865
|
-
const agentTools = db ? adaptToolsForAgent(availableToolDefs, () => ({ db, sessionId, locale }), { maxToolResultTokens }) : [];
|
|
2866
|
-
const skillMgr = new SkillManager(aiDataDir);
|
|
2867
|
-
skillMgr.init();
|
|
2868
|
-
const toolNames = agentTools.map((t) => t.name);
|
|
2869
|
-
let resolvedSkillDef;
|
|
2870
|
-
let resolvedSkillMenu;
|
|
2871
|
-
if (isChartCapability) {
|
|
2872
|
-
const def = chartRuntime.skillDef ?? getChartCapabilitySkill(locale ?? "zh-CN");
|
|
2873
|
-
resolvedSkillDef = { name: def.name, prompt: def.prompt };
|
|
2874
|
-
} else if (skillId) {
|
|
2875
|
-
const def = skillMgr.getSkillConfig(skillId);
|
|
2876
|
-
if (def) resolvedSkillDef = { name: def.name, prompt: def.prompt };
|
|
2877
|
-
} else if (enableAutoSkill) {
|
|
2878
|
-
const menu = buildSkillMenuWithBuiltinChart(
|
|
2879
|
-
skillMgr.getSkillMenu(chatType ?? "group", toolNames),
|
|
2880
|
-
locale,
|
|
2881
|
-
toolNames
|
|
2882
|
-
);
|
|
2883
|
-
if (menu) resolvedSkillMenu = menu;
|
|
2884
|
-
}
|
|
2885
|
-
if (resolvedSkillMenu) {
|
|
2886
|
-
const activateSkillTool = createActivateSkillTool({
|
|
2887
|
-
chatType: chatType ?? "group",
|
|
2888
|
-
allowedTools: toolNames,
|
|
2889
|
-
coreToolNames: new Set(CHART_CAPABILITY_CORE_TOOLS),
|
|
2890
|
-
locale,
|
|
2891
|
-
getSkillConfig: (id) => getSkillConfigWithBuiltinChart(id, locale, (skillConfigId) => skillMgr.getSkillConfig(skillConfigId))
|
|
2892
|
-
});
|
|
2893
|
-
agentTools.push(activateSkillTool);
|
|
2894
|
-
}
|
|
2895
|
-
const resolvedCompression = compressionConfig?.enabled ? {
|
|
2896
|
-
enabled: true,
|
|
2897
|
-
tokenThresholdPercent: compressionConfig.tokenThresholdPercent ?? 75,
|
|
2898
|
-
bufferSizePercent: compressionConfig.bufferSizePercent ?? 20,
|
|
2899
|
-
maxToolResultPercent: compressionConfig.maxToolResultPercent
|
|
2900
|
-
} : void 0;
|
|
2901
|
-
let dataSnapshot;
|
|
2902
|
-
if (db) {
|
|
2903
|
-
try {
|
|
2904
|
-
const overview = getChatOverview(db, 5);
|
|
2905
|
-
if (overview) {
|
|
2906
|
-
dataSnapshot = {
|
|
2907
|
-
name: overview.name,
|
|
2908
|
-
platform: overview.platform,
|
|
2909
|
-
type: overview.type,
|
|
2910
|
-
totalMessages: overview.totalMessages,
|
|
2911
|
-
totalMembers: overview.totalMembers,
|
|
2912
|
-
firstMessageTs: overview.firstMessageTs,
|
|
2913
|
-
lastMessageTs: overview.lastMessageTs,
|
|
2914
|
-
capturedAt: Math.floor(Date.now() / 1e3)
|
|
2915
|
-
};
|
|
2916
|
-
}
|
|
2917
|
-
} catch {
|
|
2918
|
-
}
|
|
2919
|
-
}
|
|
2920
|
-
await runServerAgent({
|
|
2921
|
-
userMessage,
|
|
2922
|
-
conversationId,
|
|
2923
|
-
historyLeafMessageId,
|
|
2924
|
-
chatType,
|
|
2925
|
-
locale,
|
|
2926
|
-
assistantSystemPrompt,
|
|
2927
|
-
skillMenu: resolvedSkillMenu,
|
|
2928
|
-
skillDef: resolvedSkillDef,
|
|
2929
|
-
compressionConfig: resolvedCompression,
|
|
2930
|
-
tools: agentTools,
|
|
2931
|
-
aiDataDir,
|
|
2932
|
-
convManager: convManager2,
|
|
2933
|
-
onEvent,
|
|
2934
|
-
abortSignal,
|
|
2935
|
-
ownerInfo,
|
|
2936
|
-
mentionedMembers,
|
|
2937
|
-
dataSnapshot,
|
|
2938
|
-
thinkingLevel
|
|
2939
|
-
});
|
|
2940
|
-
};
|
|
2941
|
-
}
|
|
2942
|
-
|
|
2943
2498
|
// ../../packages/sync/src/types.ts
|
|
2944
2499
|
var noop = () => {
|
|
2945
2500
|
};
|
|
2946
2501
|
var NOOP_LOGGER = { info: noop, warn: noop, error: noop };
|
|
2947
2502
|
|
|
2948
2503
|
// ../../packages/sync/src/data-source-manager.ts
|
|
2949
|
-
import * as
|
|
2950
|
-
import * as
|
|
2504
|
+
import * as fs6 from "fs";
|
|
2505
|
+
import * as path8 from "path";
|
|
2951
2506
|
import * as crypto from "crypto";
|
|
2952
2507
|
var CONFIG_FILE = "data-sources.json";
|
|
2953
2508
|
function generateId(prefix = "ds") {
|
|
@@ -2970,22 +2525,22 @@ function isValidDataSourceArray(data) {
|
|
|
2970
2525
|
var DataSourceManager = class {
|
|
2971
2526
|
configDir;
|
|
2972
2527
|
logger;
|
|
2973
|
-
constructor(configDir,
|
|
2528
|
+
constructor(configDir, logger) {
|
|
2974
2529
|
this.configDir = configDir;
|
|
2975
|
-
this.logger =
|
|
2530
|
+
this.logger = logger ?? NOOP_LOGGER;
|
|
2976
2531
|
}
|
|
2977
2532
|
getConfigPath() {
|
|
2978
|
-
return
|
|
2533
|
+
return path8.join(this.configDir, CONFIG_FILE);
|
|
2979
2534
|
}
|
|
2980
2535
|
ensureDir() {
|
|
2981
|
-
|
|
2536
|
+
fs6.mkdirSync(this.configDir, { recursive: true });
|
|
2982
2537
|
}
|
|
2983
2538
|
// ==================== Load / Save ====================
|
|
2984
2539
|
loadAll() {
|
|
2985
2540
|
try {
|
|
2986
2541
|
const filePath = this.getConfigPath();
|
|
2987
|
-
if (
|
|
2988
|
-
const raw =
|
|
2542
|
+
if (fs6.existsSync(filePath)) {
|
|
2543
|
+
const raw = fs6.readFileSync(filePath, "utf-8");
|
|
2989
2544
|
const parsed = JSON.parse(raw);
|
|
2990
2545
|
if (!isValidDataSourceArray(parsed)) {
|
|
2991
2546
|
this.logger.warn("[DataSource] Incompatible config format detected, returning empty.");
|
|
@@ -3004,7 +2559,7 @@ var DataSourceManager = class {
|
|
|
3004
2559
|
saveAll(sources) {
|
|
3005
2560
|
try {
|
|
3006
2561
|
this.ensureDir();
|
|
3007
|
-
|
|
2562
|
+
fs6.writeFileSync(this.getConfigPath(), JSON.stringify(sources, null, 2), "utf-8");
|
|
3008
2563
|
} catch (err) {
|
|
3009
2564
|
this.logger.error("[DataSource] Failed to save config", err);
|
|
3010
2565
|
}
|
|
@@ -3129,7 +2684,7 @@ function parseRemoteSessionsResponse(body) {
|
|
|
3129
2684
|
}
|
|
3130
2685
|
|
|
3131
2686
|
// ../../packages/sync/src/pull-engine.ts
|
|
3132
|
-
import * as
|
|
2687
|
+
import * as fs7 from "fs";
|
|
3133
2688
|
import * as crypto2 from "crypto";
|
|
3134
2689
|
var MAX_PAGES_PER_PULL = 5e3;
|
|
3135
2690
|
var PULL_OVERLAP_SECONDS = 60;
|
|
@@ -3149,7 +2704,7 @@ function parseSyncFromFile(filePath) {
|
|
|
3149
2704
|
try {
|
|
3150
2705
|
const isJsonl = filePath.endsWith(".jsonl");
|
|
3151
2706
|
if (isJsonl) {
|
|
3152
|
-
const content =
|
|
2707
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
3153
2708
|
const lines = content.trimEnd().split("\n");
|
|
3154
2709
|
for (let i = lines.length - 1; i >= Math.max(0, lines.length - 5); i--) {
|
|
3155
2710
|
try {
|
|
@@ -3168,7 +2723,7 @@ function parseSyncFromFile(filePath) {
|
|
|
3168
2723
|
}
|
|
3169
2724
|
return null;
|
|
3170
2725
|
}
|
|
3171
|
-
const raw =
|
|
2726
|
+
const raw = fs7.readFileSync(filePath, "utf-8");
|
|
3172
2727
|
const parsed = JSON.parse(raw);
|
|
3173
2728
|
if (parsed.sync && typeof parsed.sync === "object") {
|
|
3174
2729
|
const s = parsed.sync;
|
|
@@ -3182,7 +2737,7 @@ function parseSyncFromFile(filePath) {
|
|
|
3182
2737
|
function fileContainsMessages(filePath) {
|
|
3183
2738
|
try {
|
|
3184
2739
|
if (filePath.endsWith(".jsonl")) {
|
|
3185
|
-
const content =
|
|
2740
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
3186
2741
|
for (const line of content.split("\n")) {
|
|
3187
2742
|
const trimmed = line.trim();
|
|
3188
2743
|
if (!trimmed) continue;
|
|
@@ -3195,7 +2750,7 @@ function fileContainsMessages(filePath) {
|
|
|
3195
2750
|
}
|
|
3196
2751
|
return false;
|
|
3197
2752
|
}
|
|
3198
|
-
const raw =
|
|
2753
|
+
const raw = fs7.readFileSync(filePath, "utf-8");
|
|
3199
2754
|
const parsed = JSON.parse(raw);
|
|
3200
2755
|
return Array.isArray(parsed.messages) && parsed.messages.length > 0;
|
|
3201
2756
|
} catch {
|
|
@@ -3204,7 +2759,7 @@ function fileContainsMessages(filePath) {
|
|
|
3204
2759
|
}
|
|
3205
2760
|
function cleanupTempFile(filePath) {
|
|
3206
2761
|
try {
|
|
3207
|
-
if (
|
|
2762
|
+
if (fs7.existsSync(filePath)) fs7.unlinkSync(filePath);
|
|
3208
2763
|
} catch {
|
|
3209
2764
|
}
|
|
3210
2765
|
}
|
|
@@ -3264,7 +2819,7 @@ var PullEngine = class {
|
|
|
3264
2819
|
limit: ds.pullLimit
|
|
3265
2820
|
});
|
|
3266
2821
|
try {
|
|
3267
|
-
const stat2 =
|
|
2822
|
+
const stat2 = fs7.statSync(tempFile);
|
|
3268
2823
|
this.logger.info(`[Pull] "${sess.name}" page ${pageCount}: fetched ${stat2.size} bytes`);
|
|
3269
2824
|
const sync0 = parseSyncFromFile(tempFile);
|
|
3270
2825
|
if (stat2.size < 1024) {
|
|
@@ -3282,7 +2837,7 @@ var PullEngine = class {
|
|
|
3282
2837
|
since,
|
|
3283
2838
|
limit: ds.pullLimit
|
|
3284
2839
|
});
|
|
3285
|
-
const retryStat =
|
|
2840
|
+
const retryStat = fs7.statSync(retryFile);
|
|
3286
2841
|
this.logger.info(`[Pull] "${sess.name}" retry ${ri + 1}: fetched ${retryStat.size} bytes`);
|
|
3287
2842
|
const retrySync = parseSyncFromFile(retryFile);
|
|
3288
2843
|
if (retryStat.size < 1024 && !fileContainsMessages(retryFile) && retrySync?.hasMore === false) {
|
|
@@ -3556,13 +3111,13 @@ function reloadTimer(dsId, skipInitialPull = false) {
|
|
|
3556
3111
|
}
|
|
3557
3112
|
|
|
3558
3113
|
// src/sync/adapters.ts
|
|
3559
|
-
import * as
|
|
3114
|
+
import * as fs8 from "fs";
|
|
3560
3115
|
import * as os4 from "os";
|
|
3561
|
-
import * as
|
|
3116
|
+
import * as path9 from "path";
|
|
3562
3117
|
import * as crypto3 from "crypto";
|
|
3563
3118
|
function getTempFilePath(ext) {
|
|
3564
3119
|
const id = crypto3.randomBytes(8).toString("hex");
|
|
3565
|
-
return
|
|
3120
|
+
return path9.join(os4.tmpdir(), `chatlab-pull-${id}${ext}`);
|
|
3566
3121
|
}
|
|
3567
3122
|
var NodeFetcher = class {
|
|
3568
3123
|
async fetchToTempFile(baseUrl, remoteSessionId, token, params) {
|
|
@@ -3579,45 +3134,38 @@ var NodeFetcher = class {
|
|
|
3579
3134
|
const isJsonl = contentType.includes("ndjson") || contentType.includes("jsonl");
|
|
3580
3135
|
const tempFile = getTempFilePath(isJsonl ? ".jsonl" : ".json");
|
|
3581
3136
|
const buffer = Buffer.from(await response.arrayBuffer());
|
|
3582
|
-
|
|
3137
|
+
fs8.writeFileSync(tempFile, buffer);
|
|
3583
3138
|
return tempFile;
|
|
3584
3139
|
}
|
|
3585
3140
|
};
|
|
3586
|
-
function resolveNativeBinding2() {
|
|
3587
|
-
if (process.versions.electron) return void 0;
|
|
3588
|
-
const nativePath = resolveCliPath("native/better_sqlite3.node");
|
|
3589
|
-
if (fs10.existsSync(nativePath)) return nativePath;
|
|
3590
|
-
return void 0;
|
|
3591
|
-
}
|
|
3592
3141
|
var DirectImporter = class {
|
|
3593
3142
|
dbManager;
|
|
3594
|
-
nativeBinding;
|
|
3595
3143
|
logger;
|
|
3596
|
-
constructor(dbManager2,
|
|
3144
|
+
constructor(dbManager2, logger) {
|
|
3597
3145
|
this.dbManager = dbManager2;
|
|
3598
|
-
this.
|
|
3599
|
-
this.logger = logger2 ?? NOOP_LOGGER;
|
|
3146
|
+
this.logger = logger ?? NOOP_LOGGER;
|
|
3600
3147
|
}
|
|
3601
3148
|
sessionExists(sessionId) {
|
|
3602
3149
|
const dbPath = this.dbManager.getDbPath(sessionId);
|
|
3603
|
-
if (!
|
|
3150
|
+
if (!fs8.existsSync(dbPath)) return false;
|
|
3604
3151
|
try {
|
|
3605
|
-
const db =
|
|
3152
|
+
const db = this.dbManager.openRawSessionDatabase(sessionId, { readonly: true });
|
|
3606
3153
|
const row = db.prepare("SELECT COUNT(*) as cnt FROM sqlite_master WHERE type='table' AND name='message'").get();
|
|
3607
3154
|
db.close();
|
|
3608
3155
|
if (row.cnt === 0) {
|
|
3609
3156
|
this.logger.warn(`[DirectImporter] DB file exists but has no message table: ${sessionId}, removing`);
|
|
3610
3157
|
try {
|
|
3611
|
-
|
|
3158
|
+
fs8.unlinkSync(dbPath);
|
|
3612
3159
|
} catch {
|
|
3613
3160
|
}
|
|
3614
3161
|
return false;
|
|
3615
3162
|
}
|
|
3616
3163
|
return true;
|
|
3617
|
-
} catch {
|
|
3164
|
+
} catch (error) {
|
|
3165
|
+
if (error instanceof DataDirCompatibilityError) throw error;
|
|
3618
3166
|
this.logger.warn(`[DirectImporter] Cannot validate DB file: ${sessionId}, removing`);
|
|
3619
3167
|
try {
|
|
3620
|
-
|
|
3168
|
+
fs8.unlinkSync(dbPath);
|
|
3621
3169
|
} catch {
|
|
3622
3170
|
}
|
|
3623
3171
|
return false;
|
|
@@ -3638,8 +3186,7 @@ var DirectImporter = class {
|
|
|
3638
3186
|
const data = await parseFile(tempFile);
|
|
3639
3187
|
this.dbManager.close(sessionId);
|
|
3640
3188
|
const result = await importData(this.dbManager, data, {
|
|
3641
|
-
sessionId
|
|
3642
|
-
nativeBinding: this.nativeBinding
|
|
3189
|
+
sessionId
|
|
3643
3190
|
});
|
|
3644
3191
|
if (result.success) {
|
|
3645
3192
|
this.logger.info(
|
|
@@ -3664,8 +3211,7 @@ var DirectImporter = class {
|
|
|
3664
3211
|
try {
|
|
3665
3212
|
const data = await parseFile(tempFile);
|
|
3666
3213
|
const result = await importData(this.dbManager, data, {
|
|
3667
|
-
sessionId: externalId
|
|
3668
|
-
nativeBinding: this.nativeBinding
|
|
3214
|
+
sessionId: externalId
|
|
3669
3215
|
});
|
|
3670
3216
|
if (result.success) {
|
|
3671
3217
|
this.logger.info(
|
|
@@ -3737,8 +3283,8 @@ function registerAutomationRoutes(server2, ctx) {
|
|
|
3737
3283
|
if (request.query.deleteData === "true" && removed.targetSessionId) {
|
|
3738
3284
|
dbManager2.close(removed.targetSessionId);
|
|
3739
3285
|
const dbPath = dbManager2.getDbPath(removed.targetSessionId);
|
|
3740
|
-
const
|
|
3741
|
-
if (
|
|
3286
|
+
const fs10 = await import("fs");
|
|
3287
|
+
if (fs10.existsSync(dbPath)) fs10.unlinkSync(dbPath);
|
|
3742
3288
|
}
|
|
3743
3289
|
return { success: true };
|
|
3744
3290
|
});
|
|
@@ -3813,26 +3359,26 @@ function cleanupSync() {
|
|
|
3813
3359
|
// src/http/index.ts
|
|
3814
3360
|
var server = null;
|
|
3815
3361
|
var dbManager = null;
|
|
3816
|
-
var
|
|
3362
|
+
var aiChatManager = null;
|
|
3817
3363
|
function createFileConfigStorage(aiDataDir) {
|
|
3818
3364
|
return {
|
|
3819
3365
|
readJson(key) {
|
|
3820
3366
|
try {
|
|
3821
|
-
return JSON.parse(
|
|
3367
|
+
return JSON.parse(fs9.readFileSync(`${aiDataDir}/${key}.json`, "utf-8"));
|
|
3822
3368
|
} catch {
|
|
3823
3369
|
return null;
|
|
3824
3370
|
}
|
|
3825
3371
|
},
|
|
3826
3372
|
writeJson(key, data) {
|
|
3827
|
-
if (!
|
|
3828
|
-
|
|
3373
|
+
if (!fs9.existsSync(aiDataDir)) fs9.mkdirSync(aiDataDir, { recursive: true });
|
|
3374
|
+
fs9.writeFileSync(`${aiDataDir}/${key}.json`, JSON.stringify(data, null, 2), "utf-8");
|
|
3829
3375
|
}
|
|
3830
3376
|
};
|
|
3831
3377
|
}
|
|
3832
|
-
function
|
|
3378
|
+
function resolveNativeBinding2() {
|
|
3833
3379
|
if (process.versions.electron) return void 0;
|
|
3834
3380
|
const nativePath = resolveCliPath("native/better_sqlite3.node");
|
|
3835
|
-
if (
|
|
3381
|
+
if (fs9.existsSync(nativePath)) return nativePath;
|
|
3836
3382
|
return void 0;
|
|
3837
3383
|
}
|
|
3838
3384
|
function ensureToken(config) {
|
|
@@ -3864,6 +3410,7 @@ async function startHttpServer(options) {
|
|
|
3864
3410
|
const userDataDir = config.data.user_data_dir || void 0;
|
|
3865
3411
|
const pathProvider = new NodePathProvider(userDataDir);
|
|
3866
3412
|
pathProvider.ensureAllDirs();
|
|
3413
|
+
const runtime = assertCliDataDirCompatible(pathProvider, "cli");
|
|
3867
3414
|
if (hasPendingElectronDataWarning() || !verifyCliDataPath(pathProvider.getDatabaseDir())) {
|
|
3868
3415
|
console.error(
|
|
3869
3416
|
"\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"
|
|
@@ -3879,10 +3426,10 @@ async function startHttpServer(options) {
|
|
|
3879
3426
|
}
|
|
3880
3427
|
});
|
|
3881
3428
|
await migrationRunner.run();
|
|
3882
|
-
const nativeBinding =
|
|
3883
|
-
dbManager = new DatabaseManager(pathProvider, { nativeBinding });
|
|
3429
|
+
const nativeBinding = resolveNativeBinding2();
|
|
3430
|
+
dbManager = new DatabaseManager(pathProvider, { nativeBinding, runtime });
|
|
3884
3431
|
const aiDataDir = pathProvider.getAiDataDir();
|
|
3885
|
-
|
|
3432
|
+
aiChatManager = new AIChatManager(aiDataDir, { nativeBinding });
|
|
3886
3433
|
const assistantManager = getAssistantManager(aiDataDir);
|
|
3887
3434
|
const skillManagerCore = getSkillManagerCore(aiDataDir);
|
|
3888
3435
|
const llmConfigStore = new LLMConfigStore(createFileConfigStorage(aiDataDir), {
|
|
@@ -3907,17 +3454,17 @@ async function startHttpServer(options) {
|
|
|
3907
3454
|
nativeBinding,
|
|
3908
3455
|
aiContext: {
|
|
3909
3456
|
aiDataDir,
|
|
3910
|
-
|
|
3457
|
+
aiChatManager,
|
|
3911
3458
|
assistantManager,
|
|
3912
3459
|
skillManagerCore,
|
|
3913
3460
|
llmConfigStore,
|
|
3914
3461
|
customProviderStore: new CustomProviderStore(createFileConfigStorage(aiDataDir)),
|
|
3915
3462
|
customModelStore: new CustomModelStore(createFileConfigStorage(aiDataDir)),
|
|
3916
|
-
runAgentStream: createCliRunAgentStream(dbManager,
|
|
3463
|
+
runAgentStream: createCliRunAgentStream(dbManager, aiChatManager)
|
|
3917
3464
|
}
|
|
3918
3465
|
});
|
|
3919
3466
|
initSync(server, dbManager, pathProvider, { port, host, token });
|
|
3920
|
-
if (options?.webRoot &&
|
|
3467
|
+
if (options?.webRoot && fs9.existsSync(options.webRoot)) {
|
|
3921
3468
|
registerProxyRoutes(server);
|
|
3922
3469
|
const fastifyStatic = await import("@fastify/static");
|
|
3923
3470
|
await server.register(fastifyStatic.default, {
|
|
@@ -3938,9 +3485,9 @@ async function stopHttpServer() {
|
|
|
3938
3485
|
await server.close();
|
|
3939
3486
|
} finally {
|
|
3940
3487
|
cleanupSync();
|
|
3941
|
-
if (
|
|
3942
|
-
|
|
3943
|
-
|
|
3488
|
+
if (aiChatManager) {
|
|
3489
|
+
aiChatManager.close();
|
|
3490
|
+
aiChatManager = null;
|
|
3944
3491
|
}
|
|
3945
3492
|
if (dbManager) {
|
|
3946
3493
|
dbManager.closeAll();
|
|
@@ -3958,4 +3505,4 @@ export {
|
|
|
3958
3505
|
startHttpServer,
|
|
3959
3506
|
stopHttpServer
|
|
3960
3507
|
};
|
|
3961
|
-
//# sourceMappingURL=chunk-
|
|
3508
|
+
//# sourceMappingURL=chunk-SJIOPSMM.mjs.map
|