koishi-plugin-chatluna 1.3.4 → 1.3.5
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/lib/chains/chain.d.ts +1 -1
- package/lib/index.cjs +49 -28
- package/lib/index.mjs +49 -28
- package/lib/llm-core/agent/openai/index.d.ts +1 -1
- package/lib/llm-core/chat/app.cjs +82 -58
- package/lib/llm-core/chat/app.mjs +87 -66
- package/lib/llm-core/chat/infinite_context.d.ts +1 -0
- package/lib/llm-core/platform/model.cjs +6 -2
- package/lib/llm-core/platform/model.mjs +6 -2
- package/lib/utils/string.cjs +2 -0
- package/lib/utils/string.d.ts +2 -0
- package/lib/utils/string.mjs +2 -0
- package/package.json +1 -1
package/lib/chains/chain.d.ts
CHANGED
|
@@ -46,7 +46,7 @@ export declare class ChainMiddleware {
|
|
|
46
46
|
constructor(name: string, execute: ChainMiddlewareFunction, graph: ChatChainDependencyGraph);
|
|
47
47
|
before<T extends keyof ChainMiddlewareName>(name: T): this;
|
|
48
48
|
after<T extends keyof ChainMiddlewareName>(name: T): this;
|
|
49
|
-
run(session: Session, options: ChainMiddlewareContext): Promise<string |
|
|
49
|
+
run(session: Session, options: ChainMiddlewareContext): Promise<string | h[] | ChainMiddlewareRunStatus | h[][]>;
|
|
50
50
|
}
|
|
51
51
|
export interface ChainMiddlewareContext {
|
|
52
52
|
config: Config;
|
package/lib/index.cjs
CHANGED
|
@@ -1046,9 +1046,13 @@ var ChatLunaChatChain = class _ChatLunaChatChain extends import_base.ChatLunaLLM
|
|
|
1046
1046
|
requests["variables"] = Object.assign(variables ?? {}, {
|
|
1047
1047
|
prompt: (0, import_string.getMessageContent)(message.content)
|
|
1048
1048
|
});
|
|
1049
|
+
requests["variables"]["built"] = {
|
|
1050
|
+
conversationId
|
|
1051
|
+
};
|
|
1049
1052
|
requests["variables_hide"] = requests["variables"];
|
|
1050
1053
|
requests["configurable"] = {
|
|
1051
|
-
session
|
|
1054
|
+
session,
|
|
1055
|
+
conversationId
|
|
1052
1056
|
};
|
|
1053
1057
|
requests["id"] = conversationId;
|
|
1054
1058
|
const response = await (0, import_base.callChatLunaChain)(
|
|
@@ -1185,12 +1189,16 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
|
|
|
1185
1189
|
requests["variables"] = Object.assign(variables ?? {}, {
|
|
1186
1190
|
prompt: (0, import_string2.getMessageContent)(message.content)
|
|
1187
1191
|
});
|
|
1192
|
+
requests["variables"]["built"] = {
|
|
1193
|
+
conversationId
|
|
1194
|
+
};
|
|
1188
1195
|
requests["after_user_message"] = new import_messages2.HumanMessage(
|
|
1189
1196
|
AGENT_AFTER_USER_PROMPT
|
|
1190
1197
|
);
|
|
1191
1198
|
requests["variables_hide"] = requests["variables"];
|
|
1192
1199
|
requests["configurable"] = {
|
|
1193
|
-
session
|
|
1200
|
+
session,
|
|
1201
|
+
conversationId
|
|
1194
1202
|
};
|
|
1195
1203
|
this._toolsRef.update(session, messages.concat(message));
|
|
1196
1204
|
const preset = this.preset.value;
|
|
@@ -5184,7 +5192,7 @@ function apply48(ctx, config, chain) {
|
|
|
5184
5192
|
if (command2 !== "clear_room")
|
|
5185
5193
|
return 0 /* SKIPPED */;
|
|
5186
5194
|
let targetRoom = context.options.room;
|
|
5187
|
-
if (
|
|
5195
|
+
if (context.options.room_resolve != null) {
|
|
5188
5196
|
const rooms = await getAllJoinedConversationRoom(
|
|
5189
5197
|
ctx,
|
|
5190
5198
|
session,
|
|
@@ -5816,6 +5824,7 @@ var import_crypto7 = require("crypto");
|
|
|
5816
5824
|
var logger11;
|
|
5817
5825
|
function apply56(ctx, config, chain) {
|
|
5818
5826
|
logger11 = (0, import_logger7.createLogger)(ctx);
|
|
5827
|
+
const selectRoomForSession = /* @__PURE__ */ __name(async (session, joinedRooms) => pickContextualRoom(ctx, session, config, joinedRooms), "selectRoomForSession");
|
|
5819
5828
|
chain.middleware("resolve_room", async (session, context) => {
|
|
5820
5829
|
let joinRoom = await queryJoinedConversationRoom(
|
|
5821
5830
|
ctx,
|
|
@@ -5858,32 +5867,16 @@ function apply56(ctx, config, chain) {
|
|
|
5858
5867
|
session
|
|
5859
5868
|
);
|
|
5860
5869
|
if (joinedRooms.length > 0) {
|
|
5861
|
-
joinRoom =
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
(room
|
|
5870
|
+
joinRoom = await selectRoomForSession(session, joinedRooms);
|
|
5871
|
+
}
|
|
5872
|
+
if (joinRoom != null) {
|
|
5873
|
+
await switchConversationRoom(ctx, session, joinRoom.roomId);
|
|
5874
|
+
logger11.success(
|
|
5875
|
+
session.text("chatluna.room.auto_switch", [
|
|
5876
|
+
session.userId,
|
|
5877
|
+
joinRoom.roomName
|
|
5878
|
+
])
|
|
5867
5879
|
);
|
|
5868
|
-
if (config.autoCreateRoomFromUser !== true && joinRoom == null) {
|
|
5869
|
-
joinRoom = // 优先加入模版克隆房间
|
|
5870
|
-
joinedRooms.find(
|
|
5871
|
-
(room) => room.visibility === "template_clone"
|
|
5872
|
-
) ?? joinedRooms[Math.floor(Math.random() * joinedRooms.length)];
|
|
5873
|
-
}
|
|
5874
|
-
if (joinRoom != null) {
|
|
5875
|
-
await switchConversationRoom(
|
|
5876
|
-
ctx,
|
|
5877
|
-
session,
|
|
5878
|
-
joinRoom.roomId
|
|
5879
|
-
);
|
|
5880
|
-
logger11.success(
|
|
5881
|
-
session.text("chatluna.room.auto_switch", [
|
|
5882
|
-
session.userId,
|
|
5883
|
-
joinRoom.roomName
|
|
5884
|
-
])
|
|
5885
|
-
);
|
|
5886
|
-
}
|
|
5887
5880
|
}
|
|
5888
5881
|
}
|
|
5889
5882
|
if (joinRoom == null && config.autoCreateRoomFromUser !== true && !session.isDirect && (context.command?.length ?? 0) < 1) {
|
|
@@ -5979,6 +5972,34 @@ function apply56(ctx, config, chain) {
|
|
|
5979
5972
|
}).after("lifecycle-prepare");
|
|
5980
5973
|
}
|
|
5981
5974
|
__name(apply56, "apply");
|
|
5975
|
+
async function pickContextualRoom(ctx, session, config, joinedRooms) {
|
|
5976
|
+
if (joinedRooms.length === 0) {
|
|
5977
|
+
return void 0;
|
|
5978
|
+
}
|
|
5979
|
+
if (!session.isDirect && config.autoCreateRoomFromUser !== true) {
|
|
5980
|
+
const groupRooms = await ctx.database.get("chathub_room_group_member", {
|
|
5981
|
+
groupId: session.guildId,
|
|
5982
|
+
roomId: { $in: joinedRooms.map((room) => room.roomId) }
|
|
5983
|
+
});
|
|
5984
|
+
if (groupRooms.length > 0) {
|
|
5985
|
+
const scopedRoomIds = new Set(groupRooms.map((room) => room.roomId));
|
|
5986
|
+
const findScopedRoom = /* @__PURE__ */ __name((matcher) => joinedRooms.find((room) => {
|
|
5987
|
+
if (!scopedRoomIds.has(room.roomId)) {
|
|
5988
|
+
return false;
|
|
5989
|
+
}
|
|
5990
|
+
return matcher ? matcher(room) : true;
|
|
5991
|
+
}), "findScopedRoom");
|
|
5992
|
+
return findScopedRoom(
|
|
5993
|
+
(room) => room.visibility === "template_clone"
|
|
5994
|
+
) ?? findScopedRoom();
|
|
5995
|
+
}
|
|
5996
|
+
return void 0;
|
|
5997
|
+
}
|
|
5998
|
+
return joinedRooms.find(
|
|
5999
|
+
(room) => room.visibility === "private" && room.roomMasterId === session.userId
|
|
6000
|
+
) ?? joinedRooms.find((room) => room.visibility === "private") ?? joinedRooms.find((room) => room.visibility !== "template_clone") ?? joinedRooms[0];
|
|
6001
|
+
}
|
|
6002
|
+
__name(pickContextualRoom, "pickContextualRoom");
|
|
5982
6003
|
|
|
5983
6004
|
// src/middlewares/room/room_info.ts
|
|
5984
6005
|
function apply57(ctx, config, chain) {
|
package/lib/index.mjs
CHANGED
|
@@ -1021,9 +1021,13 @@ var ChatLunaChatChain = class _ChatLunaChatChain extends ChatLunaLLMChainWrapper
|
|
|
1021
1021
|
requests["variables"] = Object.assign(variables ?? {}, {
|
|
1022
1022
|
prompt: getMessageContent(message.content)
|
|
1023
1023
|
});
|
|
1024
|
+
requests["variables"]["built"] = {
|
|
1025
|
+
conversationId
|
|
1026
|
+
};
|
|
1024
1027
|
requests["variables_hide"] = requests["variables"];
|
|
1025
1028
|
requests["configurable"] = {
|
|
1026
|
-
session
|
|
1029
|
+
session,
|
|
1030
|
+
conversationId
|
|
1027
1031
|
};
|
|
1028
1032
|
requests["id"] = conversationId;
|
|
1029
1033
|
const response = await callChatLunaChain(
|
|
@@ -1168,12 +1172,16 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends ChatLunaLLMChainWra
|
|
|
1168
1172
|
requests["variables"] = Object.assign(variables ?? {}, {
|
|
1169
1173
|
prompt: getMessageContent2(message.content)
|
|
1170
1174
|
});
|
|
1175
|
+
requests["variables"]["built"] = {
|
|
1176
|
+
conversationId
|
|
1177
|
+
};
|
|
1171
1178
|
requests["after_user_message"] = new HumanMessage(
|
|
1172
1179
|
AGENT_AFTER_USER_PROMPT
|
|
1173
1180
|
);
|
|
1174
1181
|
requests["variables_hide"] = requests["variables"];
|
|
1175
1182
|
requests["configurable"] = {
|
|
1176
|
-
session
|
|
1183
|
+
session,
|
|
1184
|
+
conversationId
|
|
1177
1185
|
};
|
|
1178
1186
|
this._toolsRef.update(session, messages.concat(message));
|
|
1179
1187
|
const preset = this.preset.value;
|
|
@@ -5194,7 +5202,7 @@ function apply48(ctx, config, chain) {
|
|
|
5194
5202
|
if (command2 !== "clear_room")
|
|
5195
5203
|
return 0 /* SKIPPED */;
|
|
5196
5204
|
let targetRoom = context.options.room;
|
|
5197
|
-
if (
|
|
5205
|
+
if (context.options.room_resolve != null) {
|
|
5198
5206
|
const rooms = await getAllJoinedConversationRoom(
|
|
5199
5207
|
ctx,
|
|
5200
5208
|
session,
|
|
@@ -5826,6 +5834,7 @@ import { randomUUID as randomUUID4 } from "crypto";
|
|
|
5826
5834
|
var logger11;
|
|
5827
5835
|
function apply56(ctx, config, chain) {
|
|
5828
5836
|
logger11 = createLogger7(ctx);
|
|
5837
|
+
const selectRoomForSession = /* @__PURE__ */ __name(async (session, joinedRooms) => pickContextualRoom(ctx, session, config, joinedRooms), "selectRoomForSession");
|
|
5829
5838
|
chain.middleware("resolve_room", async (session, context) => {
|
|
5830
5839
|
let joinRoom = await queryJoinedConversationRoom(
|
|
5831
5840
|
ctx,
|
|
@@ -5868,32 +5877,16 @@ function apply56(ctx, config, chain) {
|
|
|
5868
5877
|
session
|
|
5869
5878
|
);
|
|
5870
5879
|
if (joinedRooms.length > 0) {
|
|
5871
|
-
joinRoom =
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
(room
|
|
5880
|
+
joinRoom = await selectRoomForSession(session, joinedRooms);
|
|
5881
|
+
}
|
|
5882
|
+
if (joinRoom != null) {
|
|
5883
|
+
await switchConversationRoom(ctx, session, joinRoom.roomId);
|
|
5884
|
+
logger11.success(
|
|
5885
|
+
session.text("chatluna.room.auto_switch", [
|
|
5886
|
+
session.userId,
|
|
5887
|
+
joinRoom.roomName
|
|
5888
|
+
])
|
|
5877
5889
|
);
|
|
5878
|
-
if (config.autoCreateRoomFromUser !== true && joinRoom == null) {
|
|
5879
|
-
joinRoom = // 优先加入模版克隆房间
|
|
5880
|
-
joinedRooms.find(
|
|
5881
|
-
(room) => room.visibility === "template_clone"
|
|
5882
|
-
) ?? joinedRooms[Math.floor(Math.random() * joinedRooms.length)];
|
|
5883
|
-
}
|
|
5884
|
-
if (joinRoom != null) {
|
|
5885
|
-
await switchConversationRoom(
|
|
5886
|
-
ctx,
|
|
5887
|
-
session,
|
|
5888
|
-
joinRoom.roomId
|
|
5889
|
-
);
|
|
5890
|
-
logger11.success(
|
|
5891
|
-
session.text("chatluna.room.auto_switch", [
|
|
5892
|
-
session.userId,
|
|
5893
|
-
joinRoom.roomName
|
|
5894
|
-
])
|
|
5895
|
-
);
|
|
5896
|
-
}
|
|
5897
5890
|
}
|
|
5898
5891
|
}
|
|
5899
5892
|
if (joinRoom == null && config.autoCreateRoomFromUser !== true && !session.isDirect && (context.command?.length ?? 0) < 1) {
|
|
@@ -5989,6 +5982,34 @@ function apply56(ctx, config, chain) {
|
|
|
5989
5982
|
}).after("lifecycle-prepare");
|
|
5990
5983
|
}
|
|
5991
5984
|
__name(apply56, "apply");
|
|
5985
|
+
async function pickContextualRoom(ctx, session, config, joinedRooms) {
|
|
5986
|
+
if (joinedRooms.length === 0) {
|
|
5987
|
+
return void 0;
|
|
5988
|
+
}
|
|
5989
|
+
if (!session.isDirect && config.autoCreateRoomFromUser !== true) {
|
|
5990
|
+
const groupRooms = await ctx.database.get("chathub_room_group_member", {
|
|
5991
|
+
groupId: session.guildId,
|
|
5992
|
+
roomId: { $in: joinedRooms.map((room) => room.roomId) }
|
|
5993
|
+
});
|
|
5994
|
+
if (groupRooms.length > 0) {
|
|
5995
|
+
const scopedRoomIds = new Set(groupRooms.map((room) => room.roomId));
|
|
5996
|
+
const findScopedRoom = /* @__PURE__ */ __name((matcher) => joinedRooms.find((room) => {
|
|
5997
|
+
if (!scopedRoomIds.has(room.roomId)) {
|
|
5998
|
+
return false;
|
|
5999
|
+
}
|
|
6000
|
+
return matcher ? matcher(room) : true;
|
|
6001
|
+
}), "findScopedRoom");
|
|
6002
|
+
return findScopedRoom(
|
|
6003
|
+
(room) => room.visibility === "template_clone"
|
|
6004
|
+
) ?? findScopedRoom();
|
|
6005
|
+
}
|
|
6006
|
+
return void 0;
|
|
6007
|
+
}
|
|
6008
|
+
return joinedRooms.find(
|
|
6009
|
+
(room) => room.visibility === "private" && room.roomMasterId === session.userId
|
|
6010
|
+
) ?? joinedRooms.find((room) => room.visibility === "private") ?? joinedRooms.find((room) => room.visibility !== "template_clone") ?? joinedRooms[0];
|
|
6011
|
+
}
|
|
6012
|
+
__name(pickContextualRoom, "pickContextualRoom");
|
|
5992
6013
|
|
|
5993
6014
|
// src/middlewares/room/room_info.ts
|
|
5994
6015
|
function apply57(ctx, config, chain) {
|
|
@@ -22,4 +22,4 @@ export type CreateOpenAIAgentParams = {
|
|
|
22
22
|
};
|
|
23
23
|
export declare function createOpenAIAgent({ llm, tools, prompt }: CreateOpenAIAgentParams): RunnableSequence<{
|
|
24
24
|
steps: AgentStep[];
|
|
25
|
-
}, AgentAction | AgentAction[]
|
|
25
|
+
}, AgentAction | AgentFinish | AgentAction[]>;
|
|
@@ -246,12 +246,9 @@ var InfiniteContextManager = class {
|
|
|
246
246
|
0,
|
|
247
247
|
contentStats.length - preserveCount
|
|
248
248
|
);
|
|
249
|
-
compressible = contentStats.filter(
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
}
|
|
253
|
-
return index < thresholdIndex;
|
|
254
|
-
});
|
|
249
|
+
compressible = contentStats.filter(
|
|
250
|
+
(stat, index) => index < thresholdIndex
|
|
251
|
+
);
|
|
255
252
|
if (compressible.length > 0) {
|
|
256
253
|
break;
|
|
257
254
|
}
|
|
@@ -272,10 +269,16 @@ var InfiniteContextManager = class {
|
|
|
272
269
|
return null;
|
|
273
270
|
}
|
|
274
271
|
const compressor = this._ensureInfiniteContextChain(wrapper);
|
|
275
|
-
const
|
|
272
|
+
const chunkSummaries = [];
|
|
273
|
+
const previousSummaries = compressible.filter((stat) => this._isCompressedMessage(stat.message)).map(
|
|
274
|
+
(stat) => (0, import_string2.getMessageContent)(stat.message.content)?.trim() ?? ""
|
|
275
|
+
).filter((text) => text.length > 0);
|
|
276
276
|
for (let index = 0; index < chunkStats.length; index++) {
|
|
277
277
|
const chunk = chunkStats[index];
|
|
278
|
-
const chunkMessages = chunk.map((item) => item.message);
|
|
278
|
+
const chunkMessages = chunk.map((item) => item.message).filter((message) => !this._isCompressedMessage(message));
|
|
279
|
+
if (chunkMessages.length === 0) {
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
279
282
|
const chunkText = this._formatChunkForCompression(chunkMessages);
|
|
280
283
|
const compressedText = await compressor.compressChunk({
|
|
281
284
|
chunk: chunkText,
|
|
@@ -284,40 +287,28 @@ var InfiniteContextManager = class {
|
|
|
284
287
|
if (!compressedText) {
|
|
285
288
|
continue;
|
|
286
289
|
}
|
|
287
|
-
|
|
290
|
+
chunkSummaries.push({
|
|
288
291
|
content: compressedText,
|
|
289
292
|
chunkIndex: index,
|
|
290
293
|
chunkSize: chunkMessages.length
|
|
291
294
|
});
|
|
292
295
|
}
|
|
293
|
-
if (
|
|
296
|
+
if (chunkSummaries.length === 0 && previousSummaries.length === 0) {
|
|
297
|
+
return null;
|
|
298
|
+
}
|
|
299
|
+
const finalSummary = await this._buildFinalSummary(
|
|
300
|
+
compressor,
|
|
301
|
+
previousSummaries,
|
|
302
|
+
chunkSummaries
|
|
303
|
+
);
|
|
304
|
+
if (!finalSummary) {
|
|
294
305
|
return null;
|
|
295
306
|
}
|
|
296
|
-
const aggregatedSummary = compressedSegments.map(
|
|
297
|
-
(segment, idx) => `### Segment ${idx + 1}
|
|
298
|
-
${segment.content.trim()}`
|
|
299
|
-
).join("\n\n");
|
|
300
|
-
const summaryMeta = {
|
|
301
|
-
source: "infinite-context",
|
|
302
|
-
segments: compressedSegments.length,
|
|
303
|
-
segmentDetail: compressedSegments.map((segment, idx) => ({
|
|
304
|
-
segment: idx + 1,
|
|
305
|
-
chunkIndex: segment.chunkIndex,
|
|
306
|
-
chunkSize: segment.chunkSize
|
|
307
|
-
}))
|
|
308
|
-
};
|
|
309
307
|
const compressedMessages = [
|
|
310
308
|
new import_messages.HumanMessage({
|
|
311
|
-
content:
|
|
312
|
-
${aggregatedSummary}
|
|
313
|
-
</infinite_context>`,
|
|
309
|
+
content: finalSummary.content,
|
|
314
310
|
name: "infinite_context",
|
|
315
|
-
additional_kwargs:
|
|
316
|
-
}),
|
|
317
|
-
new import_messages.AIMessage({
|
|
318
|
-
content: "Summary acknowledged. I will prioritise available tools when future turns involve these archived topics, and if no tools are available I will note the memory gap and ask the user to confirm the details.",
|
|
319
|
-
name: "infinite_context_ack",
|
|
320
|
-
additional_kwargs: summaryMeta
|
|
311
|
+
additional_kwargs: finalSummary.meta
|
|
321
312
|
})
|
|
322
313
|
];
|
|
323
314
|
const mergedMessages = [
|
|
@@ -384,33 +375,8 @@ ${aggregatedSummary}
|
|
|
384
375
|
const role = message.getType().toUpperCase();
|
|
385
376
|
const nameSuffix = message.name ? ` (${message.name})` : "";
|
|
386
377
|
const content = (0, import_string2.getMessageContent)(message.content).trim();
|
|
387
|
-
const extras = [];
|
|
388
|
-
const aiMessage = message;
|
|
389
|
-
if (Array.isArray(aiMessage.tool_calls) && aiMessage.tool_calls.length > 0) {
|
|
390
|
-
const toolCalls = aiMessage.tool_calls.map((call) => {
|
|
391
|
-
let args = "";
|
|
392
|
-
try {
|
|
393
|
-
args = JSON.stringify(call.args);
|
|
394
|
-
} catch (error) {
|
|
395
|
-
args = "[unserializable]";
|
|
396
|
-
}
|
|
397
|
-
return `${call.name} => ${args}`;
|
|
398
|
-
}).join("; ");
|
|
399
|
-
extras.push(`tool calls: ${toolCalls}`);
|
|
400
|
-
}
|
|
401
|
-
if (message.getType() === "tool") {
|
|
402
|
-
const toolMessage = message;
|
|
403
|
-
if (toolMessage.tool_call_id) {
|
|
404
|
-
extras.push(`tool call id: ${toolMessage.tool_call_id}`);
|
|
405
|
-
}
|
|
406
|
-
if (toolMessage.name) {
|
|
407
|
-
extras.push(`tool name: ${toolMessage.name}`);
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
const extraText = extras.length > 0 ? `
|
|
411
|
-
Meta: ${extras.join(", ")}` : "";
|
|
412
378
|
return `[${role}${nameSuffix}]
|
|
413
|
-
${content || "(empty)"}
|
|
379
|
+
${content || "(empty)"}`;
|
|
414
380
|
}).join("\n---\n");
|
|
415
381
|
}
|
|
416
382
|
_ensureInfiniteContextChain(wrapper) {
|
|
@@ -421,6 +387,64 @@ ${content || "(empty)"}${extraText}`;
|
|
|
421
387
|
}
|
|
422
388
|
return this._chain;
|
|
423
389
|
}
|
|
390
|
+
async _buildFinalSummary(compressor, previousSummaries, chunkSummaries) {
|
|
391
|
+
const cleanedPrevious = previousSummaries.filter(
|
|
392
|
+
(text) => text.trim().length > 0
|
|
393
|
+
);
|
|
394
|
+
const cleanedChunks = chunkSummaries.filter(
|
|
395
|
+
(summary) => summary.content.trim().length > 0
|
|
396
|
+
);
|
|
397
|
+
if (cleanedPrevious.length === 0 && cleanedChunks.length === 0) {
|
|
398
|
+
return null;
|
|
399
|
+
}
|
|
400
|
+
if (cleanedPrevious.length === 0 && cleanedChunks.length === 1) {
|
|
401
|
+
return {
|
|
402
|
+
content: cleanedChunks[0].content.trim(),
|
|
403
|
+
meta: {
|
|
404
|
+
source: "infinite-context",
|
|
405
|
+
mergedSegments: 1,
|
|
406
|
+
previousSummaries: 0,
|
|
407
|
+
chunkDetail: [
|
|
408
|
+
{
|
|
409
|
+
chunkIndex: cleanedChunks[0].chunkIndex,
|
|
410
|
+
chunkSize: cleanedChunks[0].chunkSize
|
|
411
|
+
}
|
|
412
|
+
]
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
const virtualTranscript = [];
|
|
417
|
+
if (cleanedPrevious.length > 0) {
|
|
418
|
+
virtualTranscript.push(
|
|
419
|
+
`Existing summary snapshot:
|
|
420
|
+
${cleanedPrevious.join("\n\n")}`
|
|
421
|
+
);
|
|
422
|
+
}
|
|
423
|
+
cleanedChunks.forEach((chunk, index) => {
|
|
424
|
+
virtualTranscript.push(
|
|
425
|
+
`Recent segment ${index + 1} (${chunk.chunkSize} turns):
|
|
426
|
+
${chunk.content}`
|
|
427
|
+
);
|
|
428
|
+
});
|
|
429
|
+
const mergedInput = virtualTranscript.join("\n\n---\n\n");
|
|
430
|
+
const refined = await compressor.compressChunk({
|
|
431
|
+
chunk: mergedInput,
|
|
432
|
+
conversationId: this.options.conversationId
|
|
433
|
+
});
|
|
434
|
+
const content = refined?.trim() || mergedInput;
|
|
435
|
+
return {
|
|
436
|
+
content,
|
|
437
|
+
meta: {
|
|
438
|
+
source: "infinite-context",
|
|
439
|
+
mergedSegments: cleanedChunks.length,
|
|
440
|
+
previousSummaries: cleanedPrevious.length,
|
|
441
|
+
chunkDetail: cleanedChunks.map((chunk) => ({
|
|
442
|
+
chunkIndex: chunk.chunkIndex,
|
|
443
|
+
chunkSize: chunk.chunkSize
|
|
444
|
+
}))
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
}
|
|
424
448
|
};
|
|
425
449
|
|
|
426
450
|
// src/llm-core/chat/app.ts
|
|
@@ -20,15 +20,12 @@ import { ChatLunaChatModel } from "koishi-plugin-chatluna/llm-core/platform/mode
|
|
|
20
20
|
import {
|
|
21
21
|
ModelCapabilities
|
|
22
22
|
} from "koishi-plugin-chatluna/llm-core/platform/types";
|
|
23
|
-
import { AIMessage
|
|
23
|
+
import { AIMessage, ToolMessage } from "@langchain/core/messages";
|
|
24
24
|
import { getMessageContent as getMessageContent3 } from "koishi-plugin-chatluna/utils/string";
|
|
25
25
|
import { computed } from "@vue/reactivity";
|
|
26
26
|
|
|
27
27
|
// src/llm-core/chat/infinite_context.ts
|
|
28
|
-
import {
|
|
29
|
-
AIMessage,
|
|
30
|
-
HumanMessage
|
|
31
|
-
} from "@langchain/core/messages";
|
|
28
|
+
import { HumanMessage } from "@langchain/core/messages";
|
|
32
29
|
import { getMessageContent as getMessageContent2 } from "koishi-plugin-chatluna/utils/string";
|
|
33
30
|
import { logger } from "koishi-plugin-chatluna";
|
|
34
31
|
|
|
@@ -243,12 +240,9 @@ var InfiniteContextManager = class {
|
|
|
243
240
|
0,
|
|
244
241
|
contentStats.length - preserveCount
|
|
245
242
|
);
|
|
246
|
-
compressible = contentStats.filter(
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
}
|
|
250
|
-
return index < thresholdIndex;
|
|
251
|
-
});
|
|
243
|
+
compressible = contentStats.filter(
|
|
244
|
+
(stat, index) => index < thresholdIndex
|
|
245
|
+
);
|
|
252
246
|
if (compressible.length > 0) {
|
|
253
247
|
break;
|
|
254
248
|
}
|
|
@@ -269,10 +263,16 @@ var InfiniteContextManager = class {
|
|
|
269
263
|
return null;
|
|
270
264
|
}
|
|
271
265
|
const compressor = this._ensureInfiniteContextChain(wrapper);
|
|
272
|
-
const
|
|
266
|
+
const chunkSummaries = [];
|
|
267
|
+
const previousSummaries = compressible.filter((stat) => this._isCompressedMessage(stat.message)).map(
|
|
268
|
+
(stat) => getMessageContent2(stat.message.content)?.trim() ?? ""
|
|
269
|
+
).filter((text) => text.length > 0);
|
|
273
270
|
for (let index = 0; index < chunkStats.length; index++) {
|
|
274
271
|
const chunk = chunkStats[index];
|
|
275
|
-
const chunkMessages = chunk.map((item) => item.message);
|
|
272
|
+
const chunkMessages = chunk.map((item) => item.message).filter((message) => !this._isCompressedMessage(message));
|
|
273
|
+
if (chunkMessages.length === 0) {
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
276
|
const chunkText = this._formatChunkForCompression(chunkMessages);
|
|
277
277
|
const compressedText = await compressor.compressChunk({
|
|
278
278
|
chunk: chunkText,
|
|
@@ -281,40 +281,28 @@ var InfiniteContextManager = class {
|
|
|
281
281
|
if (!compressedText) {
|
|
282
282
|
continue;
|
|
283
283
|
}
|
|
284
|
-
|
|
284
|
+
chunkSummaries.push({
|
|
285
285
|
content: compressedText,
|
|
286
286
|
chunkIndex: index,
|
|
287
287
|
chunkSize: chunkMessages.length
|
|
288
288
|
});
|
|
289
289
|
}
|
|
290
|
-
if (
|
|
290
|
+
if (chunkSummaries.length === 0 && previousSummaries.length === 0) {
|
|
291
|
+
return null;
|
|
292
|
+
}
|
|
293
|
+
const finalSummary = await this._buildFinalSummary(
|
|
294
|
+
compressor,
|
|
295
|
+
previousSummaries,
|
|
296
|
+
chunkSummaries
|
|
297
|
+
);
|
|
298
|
+
if (!finalSummary) {
|
|
291
299
|
return null;
|
|
292
300
|
}
|
|
293
|
-
const aggregatedSummary = compressedSegments.map(
|
|
294
|
-
(segment, idx) => `### Segment ${idx + 1}
|
|
295
|
-
${segment.content.trim()}`
|
|
296
|
-
).join("\n\n");
|
|
297
|
-
const summaryMeta = {
|
|
298
|
-
source: "infinite-context",
|
|
299
|
-
segments: compressedSegments.length,
|
|
300
|
-
segmentDetail: compressedSegments.map((segment, idx) => ({
|
|
301
|
-
segment: idx + 1,
|
|
302
|
-
chunkIndex: segment.chunkIndex,
|
|
303
|
-
chunkSize: segment.chunkSize
|
|
304
|
-
}))
|
|
305
|
-
};
|
|
306
301
|
const compressedMessages = [
|
|
307
302
|
new HumanMessage({
|
|
308
|
-
content:
|
|
309
|
-
${aggregatedSummary}
|
|
310
|
-
</infinite_context>`,
|
|
303
|
+
content: finalSummary.content,
|
|
311
304
|
name: "infinite_context",
|
|
312
|
-
additional_kwargs:
|
|
313
|
-
}),
|
|
314
|
-
new AIMessage({
|
|
315
|
-
content: "Summary acknowledged. I will prioritise available tools when future turns involve these archived topics, and if no tools are available I will note the memory gap and ask the user to confirm the details.",
|
|
316
|
-
name: "infinite_context_ack",
|
|
317
|
-
additional_kwargs: summaryMeta
|
|
305
|
+
additional_kwargs: finalSummary.meta
|
|
318
306
|
})
|
|
319
307
|
];
|
|
320
308
|
const mergedMessages = [
|
|
@@ -381,33 +369,8 @@ ${aggregatedSummary}
|
|
|
381
369
|
const role = message.getType().toUpperCase();
|
|
382
370
|
const nameSuffix = message.name ? ` (${message.name})` : "";
|
|
383
371
|
const content = getMessageContent2(message.content).trim();
|
|
384
|
-
const extras = [];
|
|
385
|
-
const aiMessage = message;
|
|
386
|
-
if (Array.isArray(aiMessage.tool_calls) && aiMessage.tool_calls.length > 0) {
|
|
387
|
-
const toolCalls = aiMessage.tool_calls.map((call) => {
|
|
388
|
-
let args = "";
|
|
389
|
-
try {
|
|
390
|
-
args = JSON.stringify(call.args);
|
|
391
|
-
} catch (error) {
|
|
392
|
-
args = "[unserializable]";
|
|
393
|
-
}
|
|
394
|
-
return `${call.name} => ${args}`;
|
|
395
|
-
}).join("; ");
|
|
396
|
-
extras.push(`tool calls: ${toolCalls}`);
|
|
397
|
-
}
|
|
398
|
-
if (message.getType() === "tool") {
|
|
399
|
-
const toolMessage = message;
|
|
400
|
-
if (toolMessage.tool_call_id) {
|
|
401
|
-
extras.push(`tool call id: ${toolMessage.tool_call_id}`);
|
|
402
|
-
}
|
|
403
|
-
if (toolMessage.name) {
|
|
404
|
-
extras.push(`tool name: ${toolMessage.name}`);
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
const extraText = extras.length > 0 ? `
|
|
408
|
-
Meta: ${extras.join(", ")}` : "";
|
|
409
372
|
return `[${role}${nameSuffix}]
|
|
410
|
-
${content || "(empty)"}
|
|
373
|
+
${content || "(empty)"}`;
|
|
411
374
|
}).join("\n---\n");
|
|
412
375
|
}
|
|
413
376
|
_ensureInfiniteContextChain(wrapper) {
|
|
@@ -418,6 +381,64 @@ ${content || "(empty)"}${extraText}`;
|
|
|
418
381
|
}
|
|
419
382
|
return this._chain;
|
|
420
383
|
}
|
|
384
|
+
async _buildFinalSummary(compressor, previousSummaries, chunkSummaries) {
|
|
385
|
+
const cleanedPrevious = previousSummaries.filter(
|
|
386
|
+
(text) => text.trim().length > 0
|
|
387
|
+
);
|
|
388
|
+
const cleanedChunks = chunkSummaries.filter(
|
|
389
|
+
(summary) => summary.content.trim().length > 0
|
|
390
|
+
);
|
|
391
|
+
if (cleanedPrevious.length === 0 && cleanedChunks.length === 0) {
|
|
392
|
+
return null;
|
|
393
|
+
}
|
|
394
|
+
if (cleanedPrevious.length === 0 && cleanedChunks.length === 1) {
|
|
395
|
+
return {
|
|
396
|
+
content: cleanedChunks[0].content.trim(),
|
|
397
|
+
meta: {
|
|
398
|
+
source: "infinite-context",
|
|
399
|
+
mergedSegments: 1,
|
|
400
|
+
previousSummaries: 0,
|
|
401
|
+
chunkDetail: [
|
|
402
|
+
{
|
|
403
|
+
chunkIndex: cleanedChunks[0].chunkIndex,
|
|
404
|
+
chunkSize: cleanedChunks[0].chunkSize
|
|
405
|
+
}
|
|
406
|
+
]
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
const virtualTranscript = [];
|
|
411
|
+
if (cleanedPrevious.length > 0) {
|
|
412
|
+
virtualTranscript.push(
|
|
413
|
+
`Existing summary snapshot:
|
|
414
|
+
${cleanedPrevious.join("\n\n")}`
|
|
415
|
+
);
|
|
416
|
+
}
|
|
417
|
+
cleanedChunks.forEach((chunk, index) => {
|
|
418
|
+
virtualTranscript.push(
|
|
419
|
+
`Recent segment ${index + 1} (${chunk.chunkSize} turns):
|
|
420
|
+
${chunk.content}`
|
|
421
|
+
);
|
|
422
|
+
});
|
|
423
|
+
const mergedInput = virtualTranscript.join("\n\n---\n\n");
|
|
424
|
+
const refined = await compressor.compressChunk({
|
|
425
|
+
chunk: mergedInput,
|
|
426
|
+
conversationId: this.options.conversationId
|
|
427
|
+
});
|
|
428
|
+
const content = refined?.trim() || mergedInput;
|
|
429
|
+
return {
|
|
430
|
+
content,
|
|
431
|
+
meta: {
|
|
432
|
+
source: "infinite-context",
|
|
433
|
+
mergedSegments: cleanedChunks.length,
|
|
434
|
+
previousSummaries: cleanedPrevious.length,
|
|
435
|
+
chunkDetail: cleanedChunks.map((chunk) => ({
|
|
436
|
+
chunkIndex: chunk.chunkIndex,
|
|
437
|
+
chunkSize: chunk.chunkSize
|
|
438
|
+
}))
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
}
|
|
421
442
|
};
|
|
422
443
|
|
|
423
444
|
// src/llm-core/chat/app.ts
|
|
@@ -510,7 +531,7 @@ var ChatInterface = class {
|
|
|
510
531
|
maxToken: this.preset?.value?.config?.maxOutputToken
|
|
511
532
|
});
|
|
512
533
|
const responseMessage = response.message;
|
|
513
|
-
const displayResponse = new
|
|
534
|
+
const displayResponse = new AIMessage({
|
|
514
535
|
content: responseMessage.content
|
|
515
536
|
});
|
|
516
537
|
displayResponse.additional_kwargs = responseMessage.additional_kwargs;
|
|
@@ -536,7 +557,7 @@ var ChatInterface = class {
|
|
|
536
557
|
const intermediateSteps = response["parallelIntermediateSteps"];
|
|
537
558
|
for (const parallelSteps of intermediateSteps) {
|
|
538
559
|
await this.chatHistory.addMessage(
|
|
539
|
-
new
|
|
560
|
+
new AIMessage({
|
|
540
561
|
content: "",
|
|
541
562
|
tool_calls: parallelSteps.map((step) => ({
|
|
542
563
|
id: step.action.toolCallId,
|
|
@@ -547,7 +568,7 @@ var ChatInterface = class {
|
|
|
547
568
|
);
|
|
548
569
|
for (const step of parallelSteps) {
|
|
549
570
|
await this.chatHistory.addMessage(
|
|
550
|
-
new
|
|
571
|
+
new ToolMessage({
|
|
551
572
|
content: step.observation,
|
|
552
573
|
tool_call_id: step.action.toolCallId,
|
|
553
574
|
name: step.action.tool
|
|
@@ -234,6 +234,10 @@ var ChatLunaChatModel = class extends import_chat_models.BaseChatModel {
|
|
|
234
234
|
if (maxTokenLimit != null && maxTokenLimit >= this.getModelMaxContextSize()) {
|
|
235
235
|
maxTokenLimit = this.getModelMaxContextSize();
|
|
236
236
|
}
|
|
237
|
+
let id = options?.id ?? this._options.id;
|
|
238
|
+
if (!id) {
|
|
239
|
+
id = options?.variables_hide?.["built"]?.["conversationId"];
|
|
240
|
+
}
|
|
237
241
|
return {
|
|
238
242
|
model: modelName,
|
|
239
243
|
temperature: options?.temperature ?? this._options.temperature,
|
|
@@ -244,12 +248,12 @@ var ChatLunaChatModel = class extends import_chat_models.BaseChatModel {
|
|
|
244
248
|
logitBias: options?.logitBias ?? this._options.logitBias,
|
|
245
249
|
maxTokens: options?.maxTokens ?? this._options.maxTokens,
|
|
246
250
|
maxTokenLimit,
|
|
247
|
-
variables: options?.["variables_hide"] ?? {},
|
|
251
|
+
variables: options?.["variables_hide"] ?? options?.["variables"] ?? {},
|
|
248
252
|
overrideRequestParams: options?.overrideRequestParams ?? this._options.overrideRequestParams ?? {},
|
|
249
253
|
stop: options?.stop ?? this._options.stop,
|
|
250
254
|
stream: options?.stream ?? this._options.stream,
|
|
251
255
|
tools: options?.tools ?? this._options.tools,
|
|
252
|
-
id
|
|
256
|
+
id,
|
|
253
257
|
signal: options?.signal ?? this._options.signal,
|
|
254
258
|
timeout: options?.timeout ?? this._options.timeout
|
|
255
259
|
};
|
|
@@ -216,6 +216,10 @@ var ChatLunaChatModel = class extends BaseChatModel {
|
|
|
216
216
|
if (maxTokenLimit != null && maxTokenLimit >= this.getModelMaxContextSize()) {
|
|
217
217
|
maxTokenLimit = this.getModelMaxContextSize();
|
|
218
218
|
}
|
|
219
|
+
let id = options?.id ?? this._options.id;
|
|
220
|
+
if (!id) {
|
|
221
|
+
id = options?.variables_hide?.["built"]?.["conversationId"];
|
|
222
|
+
}
|
|
219
223
|
return {
|
|
220
224
|
model: modelName,
|
|
221
225
|
temperature: options?.temperature ?? this._options.temperature,
|
|
@@ -226,12 +230,12 @@ var ChatLunaChatModel = class extends BaseChatModel {
|
|
|
226
230
|
logitBias: options?.logitBias ?? this._options.logitBias,
|
|
227
231
|
maxTokens: options?.maxTokens ?? this._options.maxTokens,
|
|
228
232
|
maxTokenLimit,
|
|
229
|
-
variables: options?.["variables_hide"] ?? {},
|
|
233
|
+
variables: options?.["variables_hide"] ?? options?.["variables"] ?? {},
|
|
230
234
|
overrideRequestParams: options?.overrideRequestParams ?? this._options.overrideRequestParams ?? {},
|
|
231
235
|
stop: options?.stop ?? this._options.stop,
|
|
232
236
|
stream: options?.stream ?? this._options.stream,
|
|
233
237
|
tools: options?.tools ?? this._options.tools,
|
|
234
|
-
id
|
|
238
|
+
id,
|
|
235
239
|
signal: options?.signal ?? this._options.signal,
|
|
236
240
|
timeout: options?.timeout ?? this._options.timeout
|
|
237
241
|
};
|
package/lib/utils/string.cjs
CHANGED
|
@@ -330,6 +330,7 @@ function getSystemPromptVariables(session, config, room) {
|
|
|
330
330
|
group_id: session.guildId ?? session.event?.guild?.id,
|
|
331
331
|
group_name: session.event?.guild?.name || session.guildId,
|
|
332
332
|
user_id: session.author?.user?.id ?? session.event?.user?.id ?? session.userId ?? "0",
|
|
333
|
+
platform: session.platform,
|
|
333
334
|
user: getNotEmptyString(
|
|
334
335
|
session.author?.nick,
|
|
335
336
|
session.author?.name,
|
|
@@ -338,6 +339,7 @@ function getSystemPromptVariables(session, config, room) {
|
|
|
338
339
|
),
|
|
339
340
|
built: {
|
|
340
341
|
preset: room.preset,
|
|
342
|
+
platform: session.platform,
|
|
341
343
|
conversationId: room.conversationId
|
|
342
344
|
},
|
|
343
345
|
noop: "",
|
package/lib/utils/string.d.ts
CHANGED
|
@@ -45,9 +45,11 @@ export declare function getSystemPromptVariables(session: Session, config: Confi
|
|
|
45
45
|
group_id: string;
|
|
46
46
|
group_name: string;
|
|
47
47
|
user_id: string;
|
|
48
|
+
platform: string;
|
|
48
49
|
user: string;
|
|
49
50
|
built: {
|
|
50
51
|
preset: string;
|
|
52
|
+
platform: string;
|
|
51
53
|
conversationId: string;
|
|
52
54
|
};
|
|
53
55
|
noop: string;
|
package/lib/utils/string.mjs
CHANGED
|
@@ -277,6 +277,7 @@ function getSystemPromptVariables(session, config, room) {
|
|
|
277
277
|
group_id: session.guildId ?? session.event?.guild?.id,
|
|
278
278
|
group_name: session.event?.guild?.name || session.guildId,
|
|
279
279
|
user_id: session.author?.user?.id ?? session.event?.user?.id ?? session.userId ?? "0",
|
|
280
|
+
platform: session.platform,
|
|
280
281
|
user: getNotEmptyString(
|
|
281
282
|
session.author?.nick,
|
|
282
283
|
session.author?.name,
|
|
@@ -285,6 +286,7 @@ function getSystemPromptVariables(session, config, room) {
|
|
|
285
286
|
),
|
|
286
287
|
built: {
|
|
287
288
|
preset: room.preset,
|
|
289
|
+
platform: session.platform,
|
|
288
290
|
conversationId: room.conversationId
|
|
289
291
|
},
|
|
290
292
|
noop: "",
|