koishi-plugin-chatluna 1.3.33 → 1.3.35

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.
Files changed (59) hide show
  1. package/lib/chains/chain.d.ts +1 -1
  2. package/lib/chains/index.cjs +49 -19
  3. package/lib/chains/index.mjs +49 -19
  4. package/lib/commands/conversation.d.ts +33 -0
  5. package/lib/config.d.ts +1 -0
  6. package/lib/index.cjs +50 -15
  7. package/lib/index.mjs +50 -15
  8. package/lib/legacy/types.d.ts +29 -0
  9. package/lib/llm-core/agent/creator.d.ts +4 -1
  10. package/lib/llm-core/agent/executor.d.ts +16 -16
  11. package/lib/llm-core/agent/index.cjs +167 -112
  12. package/lib/llm-core/agent/index.mjs +167 -112
  13. package/lib/llm-core/agent/openai/index.d.ts +1 -1
  14. package/lib/llm-core/agent/react/index.d.ts +7 -1
  15. package/lib/llm-core/agent/types.d.ts +23 -1
  16. package/lib/llm-core/chain/base.d.ts +3 -0
  17. package/lib/llm-core/chain/plugin_chat_chain.d.ts +6 -4
  18. package/lib/llm-core/chain/prompt.cjs +11 -14
  19. package/lib/llm-core/chain/prompt.d.ts +0 -1
  20. package/lib/llm-core/chain/prompt.mjs +11 -14
  21. package/lib/llm-core/chat/app.cjs +114 -93
  22. package/lib/llm-core/chat/app.d.ts +3 -6
  23. package/lib/llm-core/chat/app.mjs +118 -94
  24. package/lib/llm-core/chat/helper.d.ts +13 -0
  25. package/lib/llm-core/platform/api.cjs +0 -6
  26. package/lib/llm-core/platform/api.mjs +0 -6
  27. package/lib/llm-core/platform/service.cjs +43 -0
  28. package/lib/llm-core/platform/service.d.ts +15 -1
  29. package/lib/llm-core/platform/service.mjs +43 -0
  30. package/lib/llm-core/platform/types.d.ts +12 -0
  31. package/lib/llm-core/prompt/context_manager.d.ts +3 -1
  32. package/lib/llm-core/prompt/index.cjs +7 -0
  33. package/lib/llm-core/prompt/index.mjs +7 -0
  34. package/lib/middlewares/conversation/request_conversation.d.ts +15 -0
  35. package/lib/middlewares/conversation/resolve_conversation.d.ts +14 -0
  36. package/lib/middlewares/model/request_conversation.d.ts +15 -0
  37. package/lib/middlewares/system/conversation_manage.d.ts +27 -0
  38. package/lib/migration/legacy_tables.d.ts +16 -0
  39. package/lib/migration/room_to_conversation.d.ts +5 -0
  40. package/lib/migration/validators.d.ts +75 -0
  41. package/lib/services/chat.cjs +83 -23
  42. package/lib/services/chat.d.ts +7 -3
  43. package/lib/services/chat.mjs +83 -23
  44. package/lib/services/conversation.d.ts +101 -0
  45. package/lib/services/conversation_runtime.d.ts +61 -0
  46. package/lib/services/conversation_types.d.ts +149 -0
  47. package/lib/services/types.d.ts +8 -2
  48. package/lib/utils/archive.d.ts +5 -0
  49. package/lib/utils/chat_request.d.ts +4 -0
  50. package/lib/utils/compression.d.ts +6 -0
  51. package/lib/utils/message_content.d.ts +8 -0
  52. package/lib/utils/model.d.ts +1 -0
  53. package/lib/utils/schema.cjs +17 -7
  54. package/lib/utils/schema.d.ts +3 -0
  55. package/lib/utils/schema.mjs +16 -7
  56. package/lib/utils/time.d.ts +6 -0
  57. package/package.json +2 -2
  58. package/resources/presets/sydney.yml +1 -10
  59. package/lib/llm-core/agent/agent.d.ts +0 -142
@@ -64,7 +64,7 @@ export interface ChainMiddlewareContextOptions {
64
64
  export interface ChainMiddlewareName {
65
65
  }
66
66
  export type ChainMiddlewareFunction = (session: Session, context: ChainMiddlewareContext) => Promise<string | h[] | h[][] | ChainMiddlewareRunStatus | null>;
67
- export type ChatChainSender = (session: Session, message: (h[] | h | string)[]) => Promise<void>;
67
+ export type ChatChainSender = (session: Session, message: (h[] | h | string)[], context?: ChainMiddlewareContext) => Promise<void>;
68
68
  export declare enum ChainMiddlewareRunStatus {
69
69
  SKIPPED = 0,
70
70
  STOP = 1,
@@ -65,6 +65,26 @@ var lifecycleNames = [
65
65
  "lifecycle-send"
66
66
  ];
67
67
 
68
+ // src/utils/time.ts
69
+ function formatDuration(ms) {
70
+ if (ms < 1e3) {
71
+ return `${ms}ms`;
72
+ }
73
+ const totalSeconds = Math.floor(ms / 1e3);
74
+ const hours = Math.floor(totalSeconds / 3600);
75
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
76
+ const seconds = totalSeconds % 60;
77
+ if (hours > 0) {
78
+ return `${hours}h ${minutes}m ${seconds}s`;
79
+ }
80
+ if (minutes > 0) {
81
+ return `${minutes}m ${seconds}s`;
82
+ }
83
+ const decimal = (ms / 1e3).toFixed(2);
84
+ return `${decimal}s`;
85
+ }
86
+ __name(formatDuration, "formatDuration");
87
+
68
88
  // src/chains/chain.ts
69
89
  var logger;
70
90
  var ChatChain = class {
@@ -76,7 +96,7 @@ var ChatChain = class {
76
96
  this._senders = [];
77
97
  const defaultChatChainSender = new DefaultChatChainSender(config);
78
98
  this._senders.push(
79
- (session, messages) => defaultChatChainSender.send(session, messages)
99
+ (session, messages, context) => defaultChatChainSender.send(session, messages, context)
80
100
  );
81
101
  }
82
102
  static {
@@ -102,8 +122,10 @@ var ChatChain = class {
102
122
  message: session.content,
103
123
  ctx: ctx ?? this.ctx,
104
124
  session,
105
- options: {},
106
- send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message), "send"),
125
+ options: {
126
+ startedAt: Date.now()
127
+ },
128
+ send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message, context), "send"),
107
129
  recallThinkingMessage: this._createRecallThinkingMessage(
108
130
  {}
109
131
  )
@@ -120,11 +142,14 @@ var ChatChain = class {
120
142
  ctx,
121
143
  session,
122
144
  command,
123
- send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message), "send"),
145
+ send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message, context), "send"),
124
146
  recallThinkingMessage: this._createRecallThinkingMessage(
125
147
  {}
126
148
  ),
127
- options
149
+ options: {
150
+ ...options,
151
+ startedAt: Date.now()
152
+ }
128
153
  };
129
154
  context.recallThinkingMessage = this._createRecallThinkingMessage(context);
130
155
  const result = await this._runMiddleware(session, context);
@@ -184,7 +209,7 @@ var ChatChain = class {
184
209
  logger.debug("-".repeat(40) + "\n");
185
210
  }
186
211
  if (context.message != null && context.message !== originMessage) {
187
- await this.sendMessage(session, context.message);
212
+ await this.sendMessage(session, context.message, context);
188
213
  }
189
214
  return true;
190
215
  }
@@ -253,9 +278,9 @@ var ChatChain = class {
253
278
  const shouldLogTime = !middleware.name.startsWith("lifecycle-") && result !== 0 /* SKIPPED */ && middleware.name !== "allow_reply" && executionTime > 100;
254
279
  if (shouldLogTime) {
255
280
  logger.debug(
256
- `middleware %c executed in %d ms`,
281
+ `middleware %c executed in %s`,
257
282
  middleware.name,
258
- executionTime
283
+ formatDuration(executionTime)
259
284
  );
260
285
  }
261
286
  if (result === 1 /* STOP */) {
@@ -280,15 +305,15 @@ var ChatChain = class {
280
305
  };
281
306
  }
282
307
  }
283
- async sendMessage(session, message) {
308
+ async sendMessage(session, message, context) {
284
309
  const messages = message instanceof Array ? message : [message];
285
310
  for (const sender of this._senders) {
286
- await sender(session, messages);
311
+ await sender(session, messages, context);
287
312
  }
288
313
  }
289
314
  async _handleStopStatus(session, context, originMessage, isOutputLog) {
290
315
  if (context.message != null && context.message !== originMessage) {
291
- await this.sendMessage(session, context.message);
316
+ await this.sendMessage(session, context.message, context);
292
317
  }
293
318
  if (isOutputLog) {
294
319
  logger.debug("-".repeat(40) + "\n");
@@ -297,7 +322,7 @@ var ChatChain = class {
297
322
  async _handleMiddlewareError(session, middlewareName, error) {
298
323
  if (error instanceof import_error.ChatLunaError) {
299
324
  const message = error.errorCode === import_error.ChatLunaErrorCode.ABORTED ? session.text("chatluna.aborted") : error.message;
300
- await this.sendMessage(session, message);
325
+ await this.sendMessage(session, message, void 0);
301
326
  return;
302
327
  }
303
328
  logger.error(`chat-chain: ${middlewareName} error ${error}`);
@@ -309,7 +334,8 @@ var ChatChain = class {
309
334
  session.text("chatluna.middleware_error", [
310
335
  middlewareName,
311
336
  error.message
312
- ])
337
+ ]),
338
+ void 0
313
339
  );
314
340
  }
315
341
  };
@@ -580,7 +606,7 @@ var DefaultChatChainSender = class {
580
606
  return element;
581
607
  });
582
608
  }
583
- async send(session, messages) {
609
+ async send(session, messages, context) {
584
610
  if (!messages?.length) return;
585
611
  if (isElementArray(messages?.[0]) && messages[0][1]?.type === "markdown-qq") {
586
612
  await this.sendAsQQMarkdown(session, messages[0][0]);
@@ -590,7 +616,7 @@ var DefaultChatChainSender = class {
590
616
  await this.sendAsForward(session, messages);
591
617
  return;
592
618
  }
593
- await this.sendAsNormal(session, messages);
619
+ await this.sendAsNormal(session, messages, context);
594
620
  }
595
621
  async sendAsQQMarkdown(session, message) {
596
622
  const { user } = session.event;
@@ -628,19 +654,23 @@ var DefaultChatChainSender = class {
628
654
  }
629
655
  throw new Error(`Unsupported message type: ${typeof firstMsg}`);
630
656
  }
631
- async sendAsNormal(session, messages) {
657
+ async sendAsNormal(session, messages, context) {
632
658
  for (const message of messages) {
633
659
  const messageFragment = await this.buildMessageFragment(
634
660
  session,
635
- message
661
+ message,
662
+ context
636
663
  );
637
664
  if (!messageFragment?.length) continue;
638
665
  const processedFragment = this.processElements(messageFragment);
639
666
  await session.sendQueued(processedFragment);
640
667
  }
641
668
  }
642
- async buildMessageFragment(session, message) {
643
- const shouldAddQuote = this.config.isReplyWithAt && session.isDirect === false && session.messageId;
669
+ async buildMessageFragment(session, message, context) {
670
+ const start = context?.options?.startedAt;
671
+ const elapsed = start ? Date.now() - start : 0;
672
+ const threshold = (this.config.replyQuoteThreshold ?? 0) * 1e3;
673
+ const shouldAddQuote = this.config.isReplyWithAt && session.isDirect === false && session.messageId && elapsed >= threshold;
644
674
  const messageContent = this.convertMessageToArray(message);
645
675
  if (messageContent == null || messageContent.length < 1 || messageContent.length === 1 && messageContent.join().length === 0) {
646
676
  return;
@@ -20,6 +20,26 @@ var lifecycleNames = [
20
20
  "lifecycle-send"
21
21
  ];
22
22
 
23
+ // src/utils/time.ts
24
+ function formatDuration(ms) {
25
+ if (ms < 1e3) {
26
+ return `${ms}ms`;
27
+ }
28
+ const totalSeconds = Math.floor(ms / 1e3);
29
+ const hours = Math.floor(totalSeconds / 3600);
30
+ const minutes = Math.floor(totalSeconds % 3600 / 60);
31
+ const seconds = totalSeconds % 60;
32
+ if (hours > 0) {
33
+ return `${hours}h ${minutes}m ${seconds}s`;
34
+ }
35
+ if (minutes > 0) {
36
+ return `${minutes}m ${seconds}s`;
37
+ }
38
+ const decimal = (ms / 1e3).toFixed(2);
39
+ return `${decimal}s`;
40
+ }
41
+ __name(formatDuration, "formatDuration");
42
+
23
43
  // src/chains/chain.ts
24
44
  var logger;
25
45
  var ChatChain = class {
@@ -31,7 +51,7 @@ var ChatChain = class {
31
51
  this._senders = [];
32
52
  const defaultChatChainSender = new DefaultChatChainSender(config);
33
53
  this._senders.push(
34
- (session, messages) => defaultChatChainSender.send(session, messages)
54
+ (session, messages, context) => defaultChatChainSender.send(session, messages, context)
35
55
  );
36
56
  }
37
57
  static {
@@ -57,8 +77,10 @@ var ChatChain = class {
57
77
  message: session.content,
58
78
  ctx: ctx ?? this.ctx,
59
79
  session,
60
- options: {},
61
- send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message), "send"),
80
+ options: {
81
+ startedAt: Date.now()
82
+ },
83
+ send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message, context), "send"),
62
84
  recallThinkingMessage: this._createRecallThinkingMessage(
63
85
  {}
64
86
  )
@@ -75,11 +97,14 @@ var ChatChain = class {
75
97
  ctx,
76
98
  session,
77
99
  command,
78
- send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message), "send"),
100
+ send: /* @__PURE__ */ __name((message) => this.sendMessage(session, message, context), "send"),
79
101
  recallThinkingMessage: this._createRecallThinkingMessage(
80
102
  {}
81
103
  ),
82
- options
104
+ options: {
105
+ ...options,
106
+ startedAt: Date.now()
107
+ }
83
108
  };
84
109
  context.recallThinkingMessage = this._createRecallThinkingMessage(context);
85
110
  const result = await this._runMiddleware(session, context);
@@ -139,7 +164,7 @@ var ChatChain = class {
139
164
  logger.debug("-".repeat(40) + "\n");
140
165
  }
141
166
  if (context.message != null && context.message !== originMessage) {
142
- await this.sendMessage(session, context.message);
167
+ await this.sendMessage(session, context.message, context);
143
168
  }
144
169
  return true;
145
170
  }
@@ -208,9 +233,9 @@ var ChatChain = class {
208
233
  const shouldLogTime = !middleware.name.startsWith("lifecycle-") && result !== 0 /* SKIPPED */ && middleware.name !== "allow_reply" && executionTime > 100;
209
234
  if (shouldLogTime) {
210
235
  logger.debug(
211
- `middleware %c executed in %d ms`,
236
+ `middleware %c executed in %s`,
212
237
  middleware.name,
213
- executionTime
238
+ formatDuration(executionTime)
214
239
  );
215
240
  }
216
241
  if (result === 1 /* STOP */) {
@@ -235,15 +260,15 @@ var ChatChain = class {
235
260
  };
236
261
  }
237
262
  }
238
- async sendMessage(session, message) {
263
+ async sendMessage(session, message, context) {
239
264
  const messages = message instanceof Array ? message : [message];
240
265
  for (const sender of this._senders) {
241
- await sender(session, messages);
266
+ await sender(session, messages, context);
242
267
  }
243
268
  }
244
269
  async _handleStopStatus(session, context, originMessage, isOutputLog) {
245
270
  if (context.message != null && context.message !== originMessage) {
246
- await this.sendMessage(session, context.message);
271
+ await this.sendMessage(session, context.message, context);
247
272
  }
248
273
  if (isOutputLog) {
249
274
  logger.debug("-".repeat(40) + "\n");
@@ -252,7 +277,7 @@ var ChatChain = class {
252
277
  async _handleMiddlewareError(session, middlewareName, error) {
253
278
  if (error instanceof ChatLunaError) {
254
279
  const message = error.errorCode === ChatLunaErrorCode.ABORTED ? session.text("chatluna.aborted") : error.message;
255
- await this.sendMessage(session, message);
280
+ await this.sendMessage(session, message, void 0);
256
281
  return;
257
282
  }
258
283
  logger.error(`chat-chain: ${middlewareName} error ${error}`);
@@ -264,7 +289,8 @@ var ChatChain = class {
264
289
  session.text("chatluna.middleware_error", [
265
290
  middlewareName,
266
291
  error.message
267
- ])
292
+ ]),
293
+ void 0
268
294
  );
269
295
  }
270
296
  };
@@ -535,7 +561,7 @@ var DefaultChatChainSender = class {
535
561
  return element;
536
562
  });
537
563
  }
538
- async send(session, messages) {
564
+ async send(session, messages, context) {
539
565
  if (!messages?.length) return;
540
566
  if (isElementArray(messages?.[0]) && messages[0][1]?.type === "markdown-qq") {
541
567
  await this.sendAsQQMarkdown(session, messages[0][0]);
@@ -545,7 +571,7 @@ var DefaultChatChainSender = class {
545
571
  await this.sendAsForward(session, messages);
546
572
  return;
547
573
  }
548
- await this.sendAsNormal(session, messages);
574
+ await this.sendAsNormal(session, messages, context);
549
575
  }
550
576
  async sendAsQQMarkdown(session, message) {
551
577
  const { user } = session.event;
@@ -583,19 +609,23 @@ var DefaultChatChainSender = class {
583
609
  }
584
610
  throw new Error(`Unsupported message type: ${typeof firstMsg}`);
585
611
  }
586
- async sendAsNormal(session, messages) {
612
+ async sendAsNormal(session, messages, context) {
587
613
  for (const message of messages) {
588
614
  const messageFragment = await this.buildMessageFragment(
589
615
  session,
590
- message
616
+ message,
617
+ context
591
618
  );
592
619
  if (!messageFragment?.length) continue;
593
620
  const processedFragment = this.processElements(messageFragment);
594
621
  await session.sendQueued(processedFragment);
595
622
  }
596
623
  }
597
- async buildMessageFragment(session, message) {
598
- const shouldAddQuote = this.config.isReplyWithAt && session.isDirect === false && session.messageId;
624
+ async buildMessageFragment(session, message, context) {
625
+ const start = context?.options?.startedAt;
626
+ const elapsed = start ? Date.now() - start : 0;
627
+ const threshold = (this.config.replyQuoteThreshold ?? 0) * 1e3;
628
+ const shouldAddQuote = this.config.isReplyWithAt && session.isDirect === false && session.messageId && elapsed >= threshold;
599
629
  const messageContent = this.convertMessageToArray(message);
600
630
  if (messageContent == null || messageContent.length < 1 || messageContent.length === 1 && messageContent.join().length === 0) {
601
631
  return;
@@ -0,0 +1,33 @@
1
+ import { Context } from 'koishi';
2
+ import { Config } from '../config';
3
+ import { ChatChain } from '../chains/chain';
4
+ export declare function apply(ctx: Context, config: Config, chain: ChatChain): void;
5
+ declare module '../chains/chain' {
6
+ interface ChainMiddlewareContextOptions {
7
+ conversation_create?: {
8
+ title?: string;
9
+ preset?: string;
10
+ model?: string;
11
+ chatMode?: string;
12
+ };
13
+ conversation_manage?: {
14
+ targetConversation?: string;
15
+ presetLane?: string;
16
+ includeArchived?: boolean;
17
+ title?: string;
18
+ };
19
+ conversation_use?: {
20
+ model?: string;
21
+ preset?: string;
22
+ chatMode?: string;
23
+ };
24
+ conversation_rule?: {
25
+ model?: string;
26
+ preset?: string;
27
+ chatMode?: string;
28
+ share?: string;
29
+ lock?: string;
30
+ };
31
+ i18n_base?: string;
32
+ }
33
+ }
package/lib/config.d.ts CHANGED
@@ -13,6 +13,7 @@ export interface Config {
13
13
  attachForwardMsgIdToContext: boolean;
14
14
  isLog: boolean;
15
15
  isReplyWithAt: boolean;
16
+ replyQuoteThreshold?: number;
16
17
  allowQuoteReply: boolean;
17
18
  proxyAddress: string;
18
19
  isProxy: boolean;
package/lib/index.cjs CHANGED
@@ -34,14 +34,14 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
34
34
  // src/locales/zh-CN.schema.yml
35
35
  var require_zh_CN_schema = __commonJS({
36
36
  "src/locales/zh-CN.schema.yml"(exports2, module2) {
37
- module2.exports = { $inner: [{ $desc: "bot 配置", botNames: "设置 bot 的名称。(只有第一个名称是实际的 bot 名称,其他名称仅用于触发对话)", isNickname: "是否允许在开头匹配 bot 配置中的昵称来触发对话。", isNickNameWithContent: "是否允许在对话内容里任意匹配 bot 配置中的昵称来触发对话。" }, { $desc: "对话行为选项", allowPrivate: "是否允许在私聊中触发对话。", allowAtReply: "是否允许通过 @ bot 来触发对话。", allowQuoteReply: "是否允许通过引用 bot 的消息来触发对话。", isReplyWithAt: " bot 回复时,是否引用原消息。", isForwardMsg: "是否以合并消息的形式发送 bot 的回复。", forwardMsgMinLength: "合并消息的最小应用长度。为 0 则总是应用。设置大于 0 时,只有发送的文本大于此长度才会转为合并消息。", privateChatWithoutCommand: "在私聊中是否允许无需命令直接与 bot 对话。", allowChatWithRoomName: "是否允许使用房间名前缀触发对话。注意:启用此选项可能会显著影响 ChatLuna 的性能,建议配合过滤器仅在特定群组中启用。", randomReplyFrequency: "设置随机回复的频率。", includeQuoteReply: "是否在回复内容中包含引用消息的内容。", attachForwardMsgIdToContext: "是否将合并转发聊天记录消息的 ID 附加到上下文中。启用后,检测到聊天记录会额外追加一条 [聊天记录] 消息。" }, { $desc: "对话响应选项", sendThinkingMessage: "是否在请求处理过程中发送等待消息。", sendThinkingMessageTimeout: "设置在模型开始响应前,等待多少毫秒后发送等待消息。", thinkingMessage: "自定义等待消息的内容。", msgCooldown: "设置全局消息冷却时间(单位:秒),用于防止适配器被过于频繁地调用。", messageQueue: "设置是否启用消息队列。启用后当发送了多条消息,并且模型未响应初始消息时,会将将消息缓存合并成一条消息,并等待模型响应后再发送。", messageQueueDelay: "设置消息队列的延迟时间(单位:秒)。为 0 则不启用延迟。开启延迟后,会等待指定时间后才发送消息给模型,如果在此期间内存在未处理的消息,则将消息缓存合并成多条消息发送给模型。", showThoughtMessage: "在使用插件模式或思考模型时,是否显示思考过程。" }, { $desc: "消息渲染选项", outputMode: { $desc: "选择消息回复的渲染输出模式。" }, splitMessage: "是否启用消息分割发送。启用后,回复会被分割成多条消息发送,使其看起来更像普通用户的对话。注意:此选项不支持引用消息、原始模式和图片模式。在启用流式响应时,会进行更细化的消息分割。", censor: "是否启用文本审核服务(需要安装 censor 服务)。", rawOnCensor: "是否在 Post Handler 被触发时,将原始消息发送给模型。", streamResponse: "是否启用流式响应。启用后,bot 会在生成回复的过程中就开始发送消息,而不是等待完全生成后再发送。注意:启用此选项会导致渲染输出模式选项失效,且不支持插件模式。" }, { $desc: "黑名单选项", blackList: { $desc: "设置黑名单列表。请谨慎使用,只对需要拉黑的用户或群启用。1 表示启用黑名单,0 表示不启用黑名单。默认值为 0。" }, blockText: "设置对被拉黑用户的固定回复内容。" }, { $desc: "历史记录选项", infiniteContext: "启用「无限上下文」,当对话接近模型的上下文上限时自动压缩旧消息,保留关键话题和指令并丢弃无关内容。", infiniteContextThreshold: "设置无限上下文的触发阈值(百分比)。当对话历史的 token 数量达到模型上下文上限的该百分比时,将触发压缩。", autoDelete: "是否自动删除长期未使用的房间。", autoDeleteTimeout: "设置自动删除未使用房间的时间阈值(单位:秒)。" }, { $desc: "模型选项", defaultEmbeddings: "设置默认使用的嵌入模型。", defaultVectorStore: "设置默认使用的向量数据库。" }, { $desc: "模板房间选项", autoCreateRoomFromUser: "是否为每个用户自动创建专属房间。", defaultChatMode: "设置默认的聊天模式。", defaultModel: "设置默认使用的聊天模型。", defaultPreset: "设置默认使用的聊天预设。", autoUpdateRoomMode: { $desc: "自动更新房间配置模式。触发后,相关房间的配置将跟随模版房间的配置。", $inner: ["所有房间更新", "仅自动创建房间更新", "禁用更新"] } }, { $desc: "杂项", authSystem: { $desc: "是否启用配额组和用户权限系统(实验性功能)。启用后,各适配器设置的调用限额将失效。", $inner: [true] }, errorTemplate: "设置错误提示消息的模板(此设置在未来版本中可能会有变更)。", voiceSpeakId: "设置使用 vits 服务时的默认发音人 ID。", isLog: "是否启用调试模式。", isProxy: { $desc: "是否启用代理。启用后,ChatLuna 全家桶插件的网络请求将使用此代理。", $inner: [true] } }, [{ $desc: "代理选项", $inner: { proxyAddress: "网络请求的代理地址。填写后,ChatLuna 相关插件的网络服务将使用此代理地址。如不填写,将尝试使用 Koishi 全局配置中的代理设置。" } }], [{ $desc: "配额组选项", $inner: { authUserDefaultGroup: { $desc: "格式为 [权限等级, 初始余额, 授权组名称]。权限等级:0 为 guest,1 为 user,2 为 admin。如不了解,请勿配置。" } } }]] };
37
+ module2.exports = { $inner: [{ $desc: "bot 配置", botNames: "设置 bot 的名称。(只有第一个名称是实际的 bot 名称,其他名称仅用于触发对话)", isNickname: "是否允许在开头匹配 bot 配置中的昵称来触发对话。", isNickNameWithContent: "是否允许在对话内容里任意匹配 bot 配置中的昵称来触发对话。" }, { $desc: "对话行为选项", allowPrivate: "是否允许在私聊中触发对话。", allowAtReply: "是否允许通过 @ bot 来触发对话。", allowQuoteReply: "是否允许通过引用 bot 的消息来触发对话。", privateChatWithoutCommand: "在私聊中是否允许无需命令直接与 bot 对话。", allowChatWithRoomName: "是否允许使用房间名前缀触发对话。注意:启用此选项可能会显著影响 ChatLuna 的性能,建议配合过滤器仅在特定群组中启用。", randomReplyFrequency: "设置随机回复的频率。", includeQuoteReply: "是否在向模型的请求内容中添加被引用的消息内容", attachForwardMsgIdToContext: "是否将合并转发聊天记录消息的 ID 附加到上下文中。启用后,检测到聊天记录会额外追加一条 [聊天记录] 消息。" }, { isForwardMsg: "是否以合并消息的形式发送 bot 的回复。", forwardMsgMinLength: "合并消息的最小应用长度。为 0 则总是应用。设置大于 0 时,只有发送的文本大于此长度才会转为合并消息。" }, { isReplyWithAt: "当 bot 回复时,是否引用原消息", replyQuoteThreshold: "引用原消息的最小响应时长。为 0 则总是应用。设置大于 0 时,只有响应耗时大于此时长才会引用原消息。" }, { $desc: "对话响应选项", sendThinkingMessage: "是否在请求处理过程中发送等待消息。", sendThinkingMessageTimeout: "设置在模型开始响应前,等待多少毫秒后发送等待消息。", thinkingMessage: "自定义等待消息的内容。", msgCooldown: "设置全局消息冷却时间(单位:秒),用于防止适配器被过于频繁地调用。", messageQueue: "设置是否启用消息队列。启用后当发送了多条消息,并且模型未响应初始消息时,会将将消息缓存合并成一条消息,并等待模型响应后再发送。", messageQueueDelay: "设置消息队列的延迟时间(单位:秒)。为 0 则不启用延迟。开启延迟后,会等待指定时间后才发送消息给模型,如果在此期间内存在未处理的消息,则将消息缓存合并成多条消息发送给模型。", showThoughtMessage: "在使用插件模式或思考模型时,是否显示思考过程。" }, { $desc: "消息渲染选项", outputMode: { $desc: "选择消息回复的渲染输出模式。" }, splitMessage: "是否启用消息分割发送。启用后,回复会被分割成多条消息发送,使其看起来更像普通用户的对话。注意:此选项不支持引用消息、原始模式和图片模式。在启用流式响应时,会进行更细化的消息分割。", censor: "是否启用文本审核服务(需要安装 censor 服务)。", rawOnCensor: "是否在 Post Handler 被触发时,将原始消息发送给模型。", streamResponse: "是否启用流式响应。启用后,bot 会在生成回复的过程中就开始发送消息,而不是等待完全生成后再发送。注意:启用此选项会导致渲染输出模式选项失效,且不支持插件模式。" }, { $desc: "黑名单选项", blackList: { $desc: "设置黑名单列表。请谨慎使用,只对需要拉黑的用户或群启用。1 表示启用黑名单,0 表示不启用黑名单。默认值为 0。" }, blockText: "设置对被拉黑用户的固定回复内容。" }, { $desc: "历史记录选项", infiniteContext: "启用「无限上下文」,当对话接近模型的上下文上限时自动压缩旧消息,保留关键话题和指令并丢弃无关内容。", infiniteContextThreshold: "设置无限上下文的触发阈值(百分比)。当对话历史的 token 数量达到模型上下文上限的该百分比时,将触发压缩。", autoDelete: "是否自动删除长期未使用的房间。", autoDeleteTimeout: "设置自动删除未使用房间的时间阈值(单位:秒)。" }, { $desc: "模型选项", defaultEmbeddings: "设置默认使用的嵌入模型。", defaultVectorStore: "设置默认使用的向量数据库。" }, { $desc: "模板房间选项", autoCreateRoomFromUser: "是否为每个用户自动创建专属房间。", defaultChatMode: "设置默认的聊天模式。", defaultModel: "设置默认使用的聊天模型。", defaultPreset: "设置默认使用的聊天预设。", autoUpdateRoomMode: { $desc: "自动更新房间配置模式。触发后,相关房间的配置将跟随模版房间的配置。", $inner: ["所有房间更新", "仅自动创建房间更新", "禁用更新"] } }, { $desc: "杂项", authSystem: { $desc: "是否启用配额组和用户权限系统(实验性功能)。启用后,各适配器设置的调用限额将失效。", $inner: [true] }, errorTemplate: "设置错误提示消息的模板(此设置在未来版本中可能会有变更)。", voiceSpeakId: "设置使用 vits 服务时的默认发音人 ID。", isLog: "是否启用调试模式。", isProxy: { $desc: "是否启用代理。启用后,ChatLuna 全家桶插件的网络请求将使用此代理。", $inner: [true] } }, [{ $desc: "代理选项", $inner: { proxyAddress: "网络请求的代理地址。填写后,ChatLuna 相关插件的网络服务将使用此代理地址。如不填写,将尝试使用 Koishi 全局配置中的代理设置。" } }], [{ $desc: "配额组选项", $inner: { authUserDefaultGroup: { $desc: "格式为 [权限等级, 初始余额, 授权组名称]。权限等级:0 为 guest,1 为 user,2 为 admin。如不了解,请勿配置。" } } }]] };
38
38
  }
39
39
  });
40
40
 
41
41
  // src/locales/en-US.schema.yml
42
42
  var require_en_US_schema = __commonJS({
43
43
  "src/locales/en-US.schema.yml"(exports2, module2) {
44
- module2.exports = { $inner: [{ $desc: "Bot Configuration", botNames: "Set the bot's name. (Only the first name is the actual bot name; other names are only used to trigger conversations.)", isNickname: "Allow matching bot nickname at the beginning of a message to trigger a conversation.", isNickNameWithContent: "Allow matching bot nickname anywhere in the message content to trigger a conversation." }, { $desc: "Conversation Behavior", allowPrivate: "Enable private chat conversations.", allowAtReply: "Enable @mention triggering.", allowQuoteReply: "Enable quote triggering.", isReplyWithAt: "Quote original message in bot replies.", isForwardMsg: "Send bot replies as forwarded messages.", privateChatWithoutCommand: "Enable direct conversation in private chats without commands.", allowChatWithRoomName: "Enable room name prefix triggering. Note: May impact performance significantly. Recommended for use with filters in specific groups only.", randomReplyFrequency: "Set random reply frequency (0-100, where 0 means never and 100 means always).", forwardMsgMinLength: "Set minimum length of forwarded messages (characters).", includeQuoteReply: "Include quoted message content in replies.", attachForwardMsgIdToContext: 'Attach forward message record IDs to context. When enabled, a "[聊天记录]" marker message will be appended if forward records are detected.' }, { $desc: "Response Options", sendThinkingMessage: "Send waiting message during processing.", sendThinkingMessageTimeout: "Set timeout (ms) for waiting message dispatch.", thinkingMessage: "Customize waiting message content.", msgCooldown: "Set global message cooldown (seconds) to limit adapter calls.", messageQueue: "Enable message queue. When enabled, if multiple messages are sent and the model has not responded to the initial message, the messages will be cached and merged into one message, and will be sent after waiting for the model response.", messageQueueDelay: "Set message queue delay time (seconds). Set to 0 to disable delay. When delay is enabled, the system will wait for the specified time before sending messages to the model. If there are unprocessed messages during this period, they will be cached and merged into multiple messages to send to the model.", showThoughtMessage: "Display thinking message in plugin mode or reasoner model." }, { $desc: "Message Rendering", outputMode: { $desc: "Select message reply rendering mode." }, splitMessage: "Enable message splitting. Splits replies into multiple messages for natural conversation flow. Note: Incompatible with quoted messages, raw mode, or image mode. Stream response enables finer-grained splitting.", censor: "Enable text moderation (requires censor service).", rawOnCensor: "Whether to send the raw message to the model when the Post Handler is triggered.", streamResponse: "Enable stream response. Initiates message sending during reply generation. Note: Disables rendering output mode and incompatible with plugin mode." }, { $desc: "Blacklist Management", blackList: "Configure blacklist. Use cautiously to avoid unintended blocking. The number 1 indicates enabled blacklist. Set to zero value to unenable blacklist.", blockText: "Set fixed reply for blacklisted users." }, { $desc: "History Management", infiniteContext: "Enable automatic Infinite Context compression when history nears the model limit. Preserves critical topics and instructions while discarding noise.", infiniteContextThreshold: "Set the threshold (percentage) for triggering Infinite Context compression. Compression will be triggered when the token count of conversation history reaches this percentage of the model's context limit.", autoDelete: "Enable automatic deletion of inactive rooms.", autoDeleteTimeout: "Set inactivity threshold for room deletion (seconds)." }, { $desc: "Model Configuration", defaultEmbeddings: "Set default embedding model.", defaultVectorStore: "Set default vector database." }, { $desc: "Template Room Configuration", autoCreateRoomFromUser: "Enable automatic room creation per user.", defaultChatMode: "Set default chat mode.", defaultModel: "Set default chat model.", defaultPreset: "Set default chat preset.", autoUpdateRoomMode: { $desc: "Automatic room configuration update mode. When triggered, room settings will follow template room configuration.", $inner: ["Update all rooms", "Update auto-created rooms only", "Disable updates"] } }, { $desc: "Miscellaneous", authSystem: { $desc: "Enable quota group and user permission system (experimental). Overrides adapter call limits.", $inner: [true] }, errorTemplate: "Set error prompt message template (subject to change).", voiceSpeakId: "Set default speaker ID for vits service.", isLog: "Enable debug mode.", isProxy: { $desc: "Enable proxy for ChatLuna family plugin network requests.", $inner: [true] } }, [{ $desc: "Proxy Configuration", $inner: { proxyAddress: "Set proxy address for network requests. Falls back to Koishi global proxy settings if empty." } }], [{ $desc: "Quota Group Configuration", $inner: { authUserDefaultGroup: { $desc: "Format: [permission level, initial balance, authorization group name]. Levels: 0 (guest), 1 (user), 2 (admin). Leave unconfigured if uncertain." } } }]] };
44
+ module2.exports = { $inner: [{ $desc: "Bot Configuration", botNames: "Set the bot's name. (Only the first name is the actual bot name; other names are only used to trigger conversations.)", isNickname: "Allow matching bot nickname at the beginning of a message to trigger a conversation.", isNickNameWithContent: "Allow matching bot nickname anywhere in the message content to trigger a conversation." }, { $desc: "Conversation Behavior", allowPrivate: "Enable private chat conversations.", allowAtReply: "Enable @mention triggering.", allowQuoteReply: "Enable quote triggering.", privateChatWithoutCommand: "Enable direct conversation in private chats without commands.", allowChatWithRoomName: "Enable room name prefix triggering. Note: May impact performance significantly. Recommended for use with filters in specific groups only.", randomReplyFrequency: "Set random reply frequency (0-100, where 0 means never and 100 means always).", includeQuoteReply: "Include quoted message content in requests sent to the model.", attachForwardMsgIdToContext: 'Attach forward message record IDs to context. When enabled, a "[聊天记录]" marker message will be appended if forward records are detected.' }, { isForwardMsg: "Send bot replies as forwarded messages.", forwardMsgMinLength: "Set minimum length of forwarded messages (characters)." }, { isReplyWithAt: "Quote the original message when the bot replies.", replyQuoteThreshold: "Minimum response time required to quote the original message. Set to 0 to always apply. When greater than 0, the original message will only be quoted if the response time exceeds this threshold." }, { $desc: "Response Options", sendThinkingMessage: "Send waiting message during processing.", sendThinkingMessageTimeout: "Set timeout (ms) for waiting message dispatch.", thinkingMessage: "Customize waiting message content.", msgCooldown: "Set global message cooldown (seconds) to limit adapter calls.", messageQueue: "Enable message queue. When enabled, if multiple messages are sent and the model has not responded to the initial message, the messages will be cached and merged into one message, and will be sent after waiting for the model response.", messageQueueDelay: "Set message queue delay time (seconds). Set to 0 to disable delay. When delay is enabled, the system will wait for the specified time before sending messages to the model. If there are unprocessed messages during this period, they will be cached and merged into multiple messages to send to the model.", showThoughtMessage: "Display thinking message in plugin mode or reasoner model." }, { $desc: "Message Rendering", outputMode: { $desc: "Select message reply rendering mode." }, splitMessage: "Enable message splitting. Splits replies into multiple messages for natural conversation flow. Note: Incompatible with quoted messages, raw mode, or image mode. Stream response enables finer-grained splitting.", censor: "Enable text moderation (requires censor service).", rawOnCensor: "Whether to send the raw message to the model when the Post Handler is triggered.", streamResponse: "Enable stream response. Initiates message sending during reply generation. Note: Disables rendering output mode and incompatible with plugin mode." }, { $desc: "Blacklist Management", blackList: "Configure blacklist. Use cautiously to avoid unintended blocking. The number 1 indicates enabled blacklist. Set to zero value to unenable blacklist.", blockText: "Set fixed reply for blacklisted users." }, { $desc: "History Management", infiniteContext: "Enable automatic Infinite Context compression when history nears the model limit. Preserves critical topics and instructions while discarding noise.", infiniteContextThreshold: "Set the threshold (percentage) for triggering Infinite Context compression. Compression will be triggered when the token count of conversation history reaches this percentage of the model's context limit.", autoDelete: "Enable automatic deletion of inactive rooms.", autoDeleteTimeout: "Set inactivity threshold for room deletion (seconds)." }, { $desc: "Model Configuration", defaultEmbeddings: "Set default embedding model.", defaultVectorStore: "Set default vector database." }, { $desc: "Template Room Configuration", autoCreateRoomFromUser: "Enable automatic room creation per user.", defaultChatMode: "Set default chat mode.", defaultModel: "Set default chat model.", defaultPreset: "Set default chat preset.", autoUpdateRoomMode: { $desc: "Automatic room configuration update mode. When triggered, room settings will follow template room configuration.", $inner: ["Update all rooms", "Update auto-created rooms only", "Disable updates"] } }, { $desc: "Miscellaneous", authSystem: { $desc: "Enable quota group and user permission system (experimental). Overrides adapter call limits.", $inner: [true] }, errorTemplate: "Set error prompt message template (subject to change).", voiceSpeakId: "Set default speaker ID for vits service.", isLog: "Enable debug mode.", isProxy: { $desc: "Enable proxy for ChatLuna family plugin network requests.", $inner: [true] } }, [{ $desc: "Proxy Configuration", $inner: { proxyAddress: "Set proxy address for network requests. Falls back to Koishi global proxy settings if empty." } }], [{ $desc: "Quota Group Configuration", $inner: { authUserDefaultGroup: { $desc: "Format: [permission level, initial balance, authorization group name]. Levels: 0 (guest), 1 (user), 2 (admin). Leave unconfigured if uncertain." } } }]] };
45
45
  }
46
46
  });
47
47
 
@@ -633,7 +633,7 @@ __name(apply2, "apply");
633
633
 
634
634
  // src/commands/mcp.ts
635
635
  function apply3(ctx, config, chain) {
636
- ctx.inject(["chatluna_mcp"], (ctx2) => {
636
+ ctx.inject(["chatluna_agent"], (ctx2) => {
637
637
  ctx2.command("chatluna.mcp", { authority: 1 });
638
638
  ctx2.command("chatluna.mcp.list").action(async ({ session }) => {
639
639
  await chain.receiveCommand(session, "list_mcp_tools", {});
@@ -1135,6 +1135,7 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1135
1135
  preset;
1136
1136
  contextManager;
1137
1137
  agentMode;
1138
+ toolMask;
1138
1139
  _toolsRef;
1139
1140
  constructor({
1140
1141
  historyMemory,
@@ -1144,7 +1145,8 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1144
1145
  preset,
1145
1146
  embeddings,
1146
1147
  agentMode,
1147
- contextManager
1148
+ contextManager,
1149
+ toolMask
1148
1150
  }) {
1149
1151
  super();
1150
1152
  this.historyMemory = historyMemory;
@@ -1155,9 +1157,11 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1155
1157
  this.agentMode = agentMode ?? "react";
1156
1158
  this.preset = preset;
1157
1159
  this.contextManager = contextManager;
1160
+ this.toolMask = toolMask;
1158
1161
  this._toolsRef = (0, import_agent.createToolsRef)({
1159
1162
  tools: this.tools,
1160
- embeddings: this.embeddings
1163
+ embeddings: this.embeddings,
1164
+ toolMask: this.toolMask
1161
1165
  });
1162
1166
  this.executor = this._createExecutor();
1163
1167
  }
@@ -1167,7 +1171,8 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1167
1171
  embeddings,
1168
1172
  agentMode,
1169
1173
  variableService,
1170
- contextManager
1174
+ contextManager,
1175
+ toolMask
1171
1176
  }) {
1172
1177
  const prompt = new import_prompt2.ChatLunaChatPrompt({
1173
1178
  preset,
@@ -1185,7 +1190,8 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1185
1190
  tools,
1186
1191
  preset,
1187
1192
  variableService,
1188
- contextManager
1193
+ contextManager,
1194
+ toolMask
1189
1195
  });
1190
1196
  }
1191
1197
  _createExecutor() {
@@ -1213,11 +1219,15 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1213
1219
  variables,
1214
1220
  maxToken,
1215
1221
  messageQueue,
1216
- onAgentEvent
1222
+ onAgentEvent,
1223
+ toolMask: callToolMask,
1224
+ subagentContext
1217
1225
  }) {
1218
1226
  const requests = {
1219
1227
  input: message
1220
1228
  };
1229
+ const nextVars = Object.assign({}, variables ?? {});
1230
+ const toolMask = subagentContext?.toolMask ?? callToolMask;
1221
1231
  const chatHistory = this.historyMemory.chatHistory;
1222
1232
  const messages = await chatHistory.getMessages();
1223
1233
  if (this.agentMode === "react") {
@@ -1225,7 +1235,7 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1225
1235
  }
1226
1236
  requests["chat_history"] = [...messages];
1227
1237
  requests["id"] = conversationId;
1228
- requests["variables"] = Object.assign(variables ?? {}, {
1238
+ requests["variables"] = Object.assign(nextVars, {
1229
1239
  prompt: (0, import_string2.getMessageContent)(message.content)
1230
1240
  });
1231
1241
  requests["variables"]["built"] = {
@@ -1237,9 +1247,11 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1237
1247
  requests["variables_hide"] = requests["variables"];
1238
1248
  requests["configurable"] = {
1239
1249
  session,
1240
- conversationId
1250
+ conversationId,
1251
+ toolMask,
1252
+ subagentContext
1241
1253
  };
1242
- this._toolsRef.update(session, messages.concat(message));
1254
+ this._toolsRef.update(session, messages.concat(message), toolMask);
1243
1255
  const preset = this.preset.value;
1244
1256
  const executor = this.executor.value;
1245
1257
  let usedToken = 0;
@@ -1288,8 +1300,10 @@ var ChatLunaPluginChain = class _ChatLunaPluginChain extends import_base2.ChatLu
1288
1300
  conversationId,
1289
1301
  preset: preset.triggerKeyword[0],
1290
1302
  userId: session.userId,
1303
+ toolMask,
1291
1304
  messageQueue,
1292
- onAgentEvent
1305
+ onAgentEvent,
1306
+ subagentContext
1293
1307
  }
1294
1308
  }
1295
1309
  );
@@ -7299,15 +7313,36 @@ var Config2 = import_koishi12.Schema.intersect([
7299
7313
  allowPrivate: import_koishi12.Schema.boolean().default(true),
7300
7314
  allowAtReply: import_koishi12.Schema.boolean().default(true),
7301
7315
  allowQuoteReply: import_koishi12.Schema.boolean().default(false),
7302
- isReplyWithAt: import_koishi12.Schema.boolean().default(false),
7303
- isForwardMsg: import_koishi12.Schema.boolean().default(false),
7304
- forwardMsgMinLength: import_koishi12.Schema.number().min(0).max(400).step(1).default(0),
7305
7316
  privateChatWithoutCommand: import_koishi12.Schema.boolean().default(true),
7306
7317
  allowChatWithRoomName: import_koishi12.Schema.boolean().default(false),
7307
7318
  includeQuoteReply: import_koishi12.Schema.boolean().default(true),
7308
7319
  randomReplyFrequency: import_koishi12.Schema.percent().min(0).max(1).step(0.01).default(0).computed(),
7309
7320
  attachForwardMsgIdToContext: import_koishi12.Schema.boolean().default(false)
7310
7321
  }),
7322
+ import_koishi12.Schema.intersect([
7323
+ import_koishi12.Schema.object({
7324
+ isForwardMsg: import_koishi12.Schema.boolean().default(false)
7325
+ }),
7326
+ import_koishi12.Schema.union([
7327
+ import_koishi12.Schema.object({
7328
+ isForwardMsg: import_koishi12.Schema.const(true).required(),
7329
+ forwardMsgMinLength: import_koishi12.Schema.number().min(0).max(400).step(1).default(0)
7330
+ }),
7331
+ import_koishi12.Schema.object({})
7332
+ ])
7333
+ ]),
7334
+ import_koishi12.Schema.intersect([
7335
+ import_koishi12.Schema.object({
7336
+ isReplyWithAt: import_koishi12.Schema.boolean().default(false)
7337
+ }),
7338
+ import_koishi12.Schema.union([
7339
+ import_koishi12.Schema.object({
7340
+ isReplyWithAt: import_koishi12.Schema.const(true).required(),
7341
+ replyQuoteThreshold: import_koishi12.Schema.number().min(0).max(600).step(1).default(0)
7342
+ }),
7343
+ import_koishi12.Schema.object({})
7344
+ ])
7345
+ ]),
7311
7346
  import_koishi12.Schema.object({
7312
7347
  sendThinkingMessage: import_koishi12.Schema.boolean().default(true),
7313
7348
  sendThinkingMessageTimeout: import_koishi12.Schema.number().default(15e3),