koishi-plugin-chatluna-toolbox 0.0.5 → 0.0.7

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 (2) hide show
  1. package/lib/index.js +496 -381
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ BasicSettingsSchema: () => BasicSettingsSchema,
23
24
  Config: () => ConfigSchema,
24
25
  ConfigSchema: () => ConfigSchema,
25
26
  DEFAULT_GROUP_INFO_ITEMS: () => DEFAULT_GROUP_INFO_ITEMS,
@@ -31,6 +32,7 @@ __export(index_exports, {
31
32
  apply: () => apply,
32
33
  callOneBotAPI: () => callOneBotAPI,
33
34
  createBotInfoProvider: () => createBotInfoProvider,
35
+ createCharacterTempXmlRuntime: () => createCharacterTempXmlRuntime,
34
36
  createDeleteMessageTool: () => createDeleteMessageTool,
35
37
  createGroupInfoProvider: () => createGroupInfoProvider,
36
38
  createLogger: () => createLogger,
@@ -40,12 +42,12 @@ __export(index_exports, {
40
42
  createSetMsgEmojiTool: () => createSetMsgEmojiTool,
41
43
  createSetProfileTool: () => createSetProfileTool,
42
44
  createUserInfoProvider: () => createUserInfoProvider,
43
- createXmlInterceptor: () => createXmlInterceptor,
45
+ createXmlProcessor: () => createXmlProcessor,
44
46
  ensureOneBotSession: () => ensureOneBotSession,
45
47
  getSession: () => getSession,
46
48
  inject: () => inject,
47
49
  name: () => name,
48
- parseXmlActions: () => parseXmlActions,
50
+ parseSelfClosingXmlTags: () => parseSelfClosingXmlTags,
49
51
  registerNativeTools: () => registerNativeTools,
50
52
  registerVariables: () => registerVariables,
51
53
  registerXmlTools: () => registerXmlTools,
@@ -57,29 +59,88 @@ __export(index_exports, {
57
59
  module.exports = __toCommonJS(index_exports);
58
60
 
59
61
  // src/schema/index.ts
60
- var import_koishi4 = require("koishi");
62
+ var import_koishi5 = require("koishi");
61
63
 
62
- // src/schema/native-tools.ts
64
+ // src/schema/basic-settings.ts
63
65
  var import_koishi = require("koishi");
64
- var NativeToolsSchema = import_koishi.Schema.object({
66
+ var BasicSettingsSchema = import_koishi.Schema.object({
65
67
  enableNapCatProtocol: import_koishi.Schema.boolean().default(true).description("\u542F\u7528 NapCat OneBot \u534F\u8BAE\uFF08\u4E0E LLBot \u4E8C\u9009\u4E00\uFF09"),
66
- enableLlbotProtocol: import_koishi.Schema.boolean().default(false).description("\u542F\u7528 LLBot OneBot \u534F\u8BAE\uFF08\u4E0E NapCat \u4E8C\u9009\u4E00\uFF09"),
67
- enablePokeTool: import_koishi.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u6233\u4E00\u6233\uFF08\u5EFA\u8BAE\u4E0E XML\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"),
68
- pokeToolName: import_koishi.Schema.string().default("poke_user").description("ChatLuna \u5DE5\u5177\u540D\u79F0\uFF1A\u6233\u4E00\u6233"),
69
- enableSetSelfProfileTool: import_koishi.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F"),
70
- setSelfProfileToolName: import_koishi.Schema.string().default("set_self_profile").description("ChatLuna \u5DE5\u5177\u540D\u79F0\uFF1A\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F\uFF08\u652F\u6301\u6635\u79F0/\u7B7E\u540D/\u6027\u522B\uFF09"),
71
- enableSetGroupCardTool: import_koishi.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u4FEE\u6539\u7FA4\u6210\u5458\u6635\u79F0"),
72
- setGroupCardToolName: import_koishi.Schema.string().default("set_group_card").description("ChatLuna \u5DE5\u5177\u540D\u79F0\uFF1A\u4FEE\u6539\u7FA4\u6210\u5458\u6635\u79F0"),
73
- enableSetMsgEmojiTool: import_koishi.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u7ED9\u6D88\u606F\u6DFB\u52A0\u8868\u60C5\uFF08\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF0C\u5EFA\u8BAE\u4E0E XML\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"),
74
- setMsgEmojiToolName: import_koishi.Schema.string().default("set_msg_emoji").description("ChatLuna \u5DE5\u5177\u540D\u79F0\uFF1A\u7ED9\u6D88\u606F\u6DFB\u52A0\u8868\u60C5"),
75
- enableDeleteMessageTool: import_koishi.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u64A4\u56DE\u6D88\u606F\uFF08\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF0C\u5EFA\u8BAE\u4E0E XML\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"),
76
- deleteMessageToolName: import_koishi.Schema.string().default("delete_msg").description("ChatLuna \u5DE5\u5177\u540D\u79F0\uFF1A\u64A4\u56DE\u6D88\u606F")
68
+ enableLlbotProtocol: import_koishi.Schema.boolean().default(false).description("\u542F\u7528 LLBot OneBot \u534F\u8BAE\uFF08\u4E0E NapCat \u4E8C\u9009\u4E00\uFF09")
69
+ }).description("\u57FA\u7840\u8BBE\u7F6E");
70
+
71
+ // src/schema/native-tools.ts
72
+ var import_koishi2 = require("koishi");
73
+
74
+ // src/features/native-tools/defaults.ts
75
+ var DEFAULT_POKE_TOOL_DESCRIPTION = "\u5BF9\u6307\u5B9A\u7528\u6237\u6267\u884C\u6233\u4E00\u6233\u3002";
76
+ var DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION = "\u4FEE\u6539\u81EA\u5DF1\u7684 QQ \u8D44\u6599\uFF0C\u53EF\u8BBE\u7F6E\u6635\u79F0\u3001\u7B7E\u540D\u548C\u6027\u522B\u3002";
77
+ var DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION = "\u4FEE\u6539\u7FA4\u6210\u5458\u7684\u7FA4\u6635\u79F0\u3002";
78
+ var DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION = "\u5BF9\u6307\u5B9A\u6D88\u606F\u6DFB\u52A0\u8868\u60C5\u56DE\u5E94\u3002";
79
+ var DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION = "\u6839\u636E\u6D88\u606F ID \u64A4\u56DE\u6307\u5B9A\u6D88\u606F\u3002";
80
+
81
+ // src/schema/native-tools.ts
82
+ var NativeToolsSchema = import_koishi2.Schema.object({
83
+ poke: import_koishi2.Schema.object({
84
+ enabled: import_koishi2.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u6233\u4E00\u6233\uFF08\u4E0E XML\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"),
85
+ toolName: import_koishi2.Schema.string().default("poke_user").description("\u5DE5\u5177\u540D\u79F0"),
86
+ description: import_koishi2.Schema.string().default(DEFAULT_POKE_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
87
+ }).description("\u6233\u4E00\u6233\u5DE5\u5177").collapse(),
88
+ setSelfProfile: import_koishi2.Schema.object({
89
+ enabled: import_koishi2.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F\uFF08\u652F\u6301\u6635\u79F0/\u7B7E\u540D/\u6027\u522B\uFF09"),
90
+ toolName: import_koishi2.Schema.string().default("set_self_profile").description("\u5DE5\u5177\u540D\u79F0"),
91
+ description: import_koishi2.Schema.string().default(DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
92
+ }).description("\u4FEE\u6539\u81EA\u8EAB\u8D26\u6237\u4FE1\u606F\u5DE5\u5177").collapse(),
93
+ setGroupCard: import_koishi2.Schema.object({
94
+ enabled: import_koishi2.Schema.boolean().default(false).description("\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u4FEE\u6539\u7FA4\u6210\u5458\u6635\u79F0"),
95
+ toolName: import_koishi2.Schema.string().default("set_group_card").description("\u5DE5\u5177\u540D\u79F0"),
96
+ description: import_koishi2.Schema.string().default(DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
97
+ }).description("\u4FEE\u6539\u7FA4\u6210\u5458\u6635\u79F0\u5DE5\u5177").collapse(),
98
+ setMsgEmoji: import_koishi2.Schema.object({
99
+ enabled: import_koishi2.Schema.boolean().default(false).description(
100
+ "\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u7ED9\u6D88\u606F\u6DFB\u52A0\u8868\u60C5\uFF08\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF0C\u4E0E XML\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF0C\u8868\u60C5\u5BF9\u7167\u8868\uFF1Ahttps://bot.q.qq.com/wiki/develop/pythonsdk/model/emoji.html \uFF09"
101
+ ),
102
+ toolName: import_koishi2.Schema.string().default("set_msg_emoji").description("\u5DE5\u5177\u540D\u79F0"),
103
+ description: import_koishi2.Schema.string().default(DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
104
+ }).description("\u6D88\u606F\u8868\u60C5\u5DE5\u5177").collapse(),
105
+ deleteMessage: import_koishi2.Schema.object({
106
+ enabled: import_koishi2.Schema.boolean().default(false).description(
107
+ "\u6CE8\u518C ChatLuna \u5DE5\u5177\uFF1A\u64A4\u56DE\u6D88\u606F\uFF08\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF0C\u4E0E XML\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"
108
+ ),
109
+ toolName: import_koishi2.Schema.string().default("delete_msg").description("\u5DE5\u5177\u540D\u79F0"),
110
+ description: import_koishi2.Schema.string().default(DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION).description("\u5DE5\u5177\u63CF\u8FF0")
111
+ }).description("\u64A4\u56DE\u6D88\u606F\u5DE5\u5177").collapse()
112
+ }).default({
113
+ poke: {
114
+ enabled: false,
115
+ toolName: "poke_user",
116
+ description: DEFAULT_POKE_TOOL_DESCRIPTION
117
+ },
118
+ setSelfProfile: {
119
+ enabled: false,
120
+ toolName: "set_self_profile",
121
+ description: DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION
122
+ },
123
+ setGroupCard: {
124
+ enabled: false,
125
+ toolName: "set_group_card",
126
+ description: DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION
127
+ },
128
+ setMsgEmoji: {
129
+ enabled: false,
130
+ toolName: "set_msg_emoji",
131
+ description: DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION
132
+ },
133
+ deleteMessage: {
134
+ enabled: false,
135
+ toolName: "delete_msg",
136
+ description: DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION
137
+ }
77
138
  }).description("\u539F\u751F\u5DE5\u5177");
78
139
 
79
140
  // src/schema/xml-tools.ts
80
- var import_koishi2 = require("koishi");
141
+ var import_koishi3 = require("koishi");
81
142
  var DEFAULT_XML_REFERENCE_PROMPT = `## \u52A8\u4F5C\u6307\u4EE4
82
- \u4F60\u53EF\u4EE5\u6839\u636E\u9700\u8981\u521B\u5EFA\u4E00\u4E2A\u72EC\u7ACB\u7684 <actions> \u5143\u7D20\u3002\u5B83\u7528\u4E8E\u6267\u884C\u975E\u8BED\u8A00\u7684\u7CFB\u7EDF\u6307\u4EE4\u3002\u5982\u679C\u4E0D\u9700\u8981\u6267\u884C\u4EFB\u4F55\u52A8\u4F5C\uFF0C\u8BF7\u7701\u7565\u6B64\u5143\u7D20\u3002
143
+ \u4F60\u53EF\u4EE5\u6839\u636E\u9700\u8981\u5728\u6A21\u578B\u56DE\u590D\u4E2D\u8F93\u51FA\u4E00\u4E2A\u72EC\u7ACB\u7684 <actions> \u5143\u7D20\u3002\u5B83\u7528\u4E8E\u6267\u884C\u975E\u8BED\u8A00\u7684\u7CFB\u7EDF\u6307\u4EE4\u3002\u5982\u679C\u4E0D\u9700\u8981\u6267\u884C\u4EFB\u4F55\u52A8\u4F5C\uFF0C\u8BF7\u7701\u7565\u6B64\u5143\u7D20\u3002
83
144
  1. \u6233\u4E00\u6233: <poke id=""/>
84
145
  - id: user_id
85
146
  - \u9002\u7528\u573A\u666F:
@@ -110,15 +171,17 @@ var DEFAULT_XML_REFERENCE_PROMPT = `## \u52A8\u4F5C\u6307\u4EE4
110
171
  <delete message_id="435663"/>
111
172
  </actions>
112
173
  \`\`\``;
113
- var XmlToolsSchema = import_koishi2.Schema.object({
114
- enablePokeXmlTool: import_koishi2.Schema.boolean().default(false).description("\u542F\u7528 XML \u5F62\u5F0F\u7684\u6233\u4E00\u6233\u8C03\u7528"),
115
- enableEmojiXmlTool: import_koishi2.Schema.boolean().default(false).description("\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u8868\u60C5\u8C03\u7528"),
116
- enableDeleteXmlTool: import_koishi2.Schema.boolean().default(false).description("\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u64A4\u56DE\u8C03\u7528"),
117
- referencePrompt: import_koishi2.Schema.string().role("textarea").default(DEFAULT_XML_REFERENCE_PROMPT).description("\u53C2\u8003\u63D0\u793A\u8BCD")
174
+ var XmlToolsSchema = import_koishi3.Schema.object({
175
+ enablePokeXmlTool: import_koishi3.Schema.boolean().default(false).description("\u542F\u7528 XML \u5F62\u5F0F\u7684\u6233\u4E00\u6233\u8C03\u7528\uFF08\u4E0E \u539F\u751F\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"),
176
+ enableEmojiXmlTool: import_koishi3.Schema.boolean().default(false).description(
177
+ "\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u8868\u60C5\u8C03\u7528\uFF0C\uFF08\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF0C\u4E0E \u539F\u751F\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF0Cemoji_id \u5BF9\u7167\u8868\uFF1Ahttps://bot.q.qq.com/wiki/develop/pythonsdk/model/emoji.html \uFF09"
178
+ ),
179
+ enableDeleteXmlTool: import_koishi3.Schema.boolean().default(false).description("\u542F\u7528 XML \u5F62\u5F0F\u7684\u6D88\u606F\u64A4\u56DE\u8C03\u7528\uFF08\u9700 chatluna-character \u5F00\u542F enableMessageId\uFF0C\u4E0E \u539F\u751F\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"),
180
+ referencePrompt: import_koishi3.Schema.string().role("textarea").default(DEFAULT_XML_REFERENCE_PROMPT).description("\u6A21\u578B\u56DE\u590D XML \u53C2\u8003\u63D0\u793A\u8BCD\uFF0C\u81EA\u884C\u5199\u5165\u63D0\u793A\u8BCD\u4E2D\uFF0C\u4E0D\u4F1A\u81EA\u52A8\u6CE8\u5165")
118
181
  }).description("XML \u5DE5\u5177");
119
182
 
120
183
  // src/schema/variables.ts
121
- var import_koishi3 = require("koishi");
184
+ var import_koishi4 = require("koishi");
122
185
 
123
186
  // src/constants/defaults.ts
124
187
  var DEFAULT_MEMBER_INFO_ITEMS = [
@@ -143,58 +206,58 @@ var DEFAULT_GROUP_INFO_ITEMS = [
143
206
  var RAW_INTERCEPTOR_TAG = "__chatlunaToolboxRawInterceptor";
144
207
 
145
208
  // src/schema/variables.ts
146
- var VariablesSchema = import_koishi3.Schema.object({
147
- userInfo: import_koishi3.Schema.object({
148
- variableName: import_koishi3.Schema.string().default("userInfo").description("\u53D8\u91CF\u540D\u79F0"),
149
- items: import_koishi3.Schema.array(
150
- import_koishi3.Schema.union([
151
- import_koishi3.Schema.const("userId").description("\u7528\u6237 ID"),
152
- import_koishi3.Schema.const("nickname").description("\u7FA4\u6635\u79F0"),
153
- import_koishi3.Schema.const("role").description("\u7FA4\u5185\u8EAB\u4EFD"),
154
- import_koishi3.Schema.const("level").description("\u7FA4\u7B49\u7EA7"),
155
- import_koishi3.Schema.const("title").description("\u7FA4\u5934\u8854"),
156
- import_koishi3.Schema.const("gender").description("\u6027\u522B"),
157
- import_koishi3.Schema.const("age").description("\u5E74\u9F84"),
158
- import_koishi3.Schema.const("area").description("\u5730\u533A"),
159
- import_koishi3.Schema.const("joinTime").description("\u5165\u7FA4\u65F6\u95F4"),
160
- import_koishi3.Schema.const("lastSentTime").description("\u6700\u540E\u53D1\u8A00\u65F6\u95F4")
209
+ var VariablesSchema = import_koishi4.Schema.object({
210
+ userInfo: import_koishi4.Schema.object({
211
+ variableName: import_koishi4.Schema.string().default("userInfo").description("\u53D8\u91CF\u540D\u79F0"),
212
+ items: import_koishi4.Schema.array(
213
+ import_koishi4.Schema.union([
214
+ import_koishi4.Schema.const("userId").description("\u7528\u6237 ID"),
215
+ import_koishi4.Schema.const("nickname").description("\u7FA4\u6635\u79F0"),
216
+ import_koishi4.Schema.const("role").description("\u7FA4\u5185\u8EAB\u4EFD"),
217
+ import_koishi4.Schema.const("level").description("\u7FA4\u7B49\u7EA7"),
218
+ import_koishi4.Schema.const("title").description("\u7FA4\u5934\u8854"),
219
+ import_koishi4.Schema.const("gender").description("\u6027\u522B"),
220
+ import_koishi4.Schema.const("age").description("\u5E74\u9F84"),
221
+ import_koishi4.Schema.const("area").description("\u5730\u533A"),
222
+ import_koishi4.Schema.const("joinTime").description("\u5165\u7FA4\u65F6\u95F4"),
223
+ import_koishi4.Schema.const("lastSentTime").description("\u6700\u540E\u53D1\u8A00\u65F6\u95F4")
161
224
  ])
162
225
  ).role("checkbox").default([...DEFAULT_MEMBER_INFO_ITEMS]).description("\u663E\u793A\u7684\u8BE6\u7EC6\u4FE1\u606F\u9879")
163
226
  }).description("\u7528\u6237\u4FE1\u606F\u53D8\u91CF").collapse(),
164
- botInfo: import_koishi3.Schema.object({
165
- variableName: import_koishi3.Schema.string().default("botInfo").description("\u53D8\u91CF\u540D\u79F0"),
166
- items: import_koishi3.Schema.array(
167
- import_koishi3.Schema.union([
168
- import_koishi3.Schema.const("userId").description("\u673A\u5668\u4EBA ID"),
169
- import_koishi3.Schema.const("nickname").description("\u7FA4\u6635\u79F0"),
170
- import_koishi3.Schema.const("role").description("\u7FA4\u5185\u8EAB\u4EFD"),
171
- import_koishi3.Schema.const("level").description("\u7FA4\u7B49\u7EA7"),
172
- import_koishi3.Schema.const("title").description("\u7FA4\u5934\u8854"),
173
- import_koishi3.Schema.const("gender").description("\u6027\u522B"),
174
- import_koishi3.Schema.const("age").description("\u5E74\u9F84"),
175
- import_koishi3.Schema.const("area").description("\u5730\u533A"),
176
- import_koishi3.Schema.const("joinTime").description("\u5165\u7FA4\u65F6\u95F4"),
177
- import_koishi3.Schema.const("lastSentTime").description("\u6700\u540E\u53D1\u8A00\u65F6\u95F4")
227
+ botInfo: import_koishi4.Schema.object({
228
+ variableName: import_koishi4.Schema.string().default("botInfo").description("\u53D8\u91CF\u540D\u79F0"),
229
+ items: import_koishi4.Schema.array(
230
+ import_koishi4.Schema.union([
231
+ import_koishi4.Schema.const("userId").description("\u673A\u5668\u4EBA ID"),
232
+ import_koishi4.Schema.const("nickname").description("\u7FA4\u6635\u79F0"),
233
+ import_koishi4.Schema.const("role").description("\u7FA4\u5185\u8EAB\u4EFD"),
234
+ import_koishi4.Schema.const("level").description("\u7FA4\u7B49\u7EA7"),
235
+ import_koishi4.Schema.const("title").description("\u7FA4\u5934\u8854"),
236
+ import_koishi4.Schema.const("gender").description("\u6027\u522B"),
237
+ import_koishi4.Schema.const("age").description("\u5E74\u9F84"),
238
+ import_koishi4.Schema.const("area").description("\u5730\u533A"),
239
+ import_koishi4.Schema.const("joinTime").description("\u5165\u7FA4\u65F6\u95F4"),
240
+ import_koishi4.Schema.const("lastSentTime").description("\u6700\u540E\u53D1\u8A00\u65F6\u95F4")
178
241
  ])
179
242
  ).role("checkbox").default([...DEFAULT_MEMBER_INFO_ITEMS]).description("\u663E\u793A\u7684\u673A\u5668\u4EBA\u8BE6\u7EC6\u4FE1\u606F\u9879")
180
243
  }).description("\u673A\u5668\u4EBA\u4FE1\u606F\u53D8\u91CF").collapse(),
181
- groupInfo: import_koishi3.Schema.object({
182
- variableName: import_koishi3.Schema.string().default("groupInfo").description("\u53D8\u91CF\u540D\u79F0"),
183
- items: import_koishi3.Schema.array(
184
- import_koishi3.Schema.union([
185
- import_koishi3.Schema.const("groupName").description("\u7FA4\u540D\u79F0"),
186
- import_koishi3.Schema.const("groupId").description("\u7FA4\u53F7"),
187
- import_koishi3.Schema.const("memberCount").description("\u6210\u5458\u6570\u91CF"),
188
- import_koishi3.Schema.const("createTime").description("\u521B\u5EFA\u65F6\u95F4\uFF08\u4EC5\u90E8\u5206\u5B9E\u73B0\u652F\u6301\uFF09"),
189
- import_koishi3.Schema.const("ownerList").description("\u7FA4\u4E3B\u540D\u5355"),
190
- import_koishi3.Schema.const("adminList").description("\u7BA1\u7406\u5458\u540D\u5355")
244
+ groupInfo: import_koishi4.Schema.object({
245
+ variableName: import_koishi4.Schema.string().default("groupInfo").description("\u53D8\u91CF\u540D\u79F0"),
246
+ items: import_koishi4.Schema.array(
247
+ import_koishi4.Schema.union([
248
+ import_koishi4.Schema.const("groupName").description("\u7FA4\u540D\u79F0"),
249
+ import_koishi4.Schema.const("groupId").description("\u7FA4\u53F7"),
250
+ import_koishi4.Schema.const("memberCount").description("\u6210\u5458\u6570\u91CF"),
251
+ import_koishi4.Schema.const("createTime").description("\u521B\u5EFA\u65F6\u95F4\uFF08\u4EC5\u90E8\u5206\u5B9E\u73B0\u652F\u6301\uFF09"),
252
+ import_koishi4.Schema.const("ownerList").description("\u7FA4\u4E3B\u540D\u5355"),
253
+ import_koishi4.Schema.const("adminList").description("\u7BA1\u7406\u5458\u540D\u5355")
191
254
  ])
192
255
  ).role("checkbox").default([...DEFAULT_GROUP_INFO_ITEMS]).description("\u663E\u793A\u7684\u7FA4\u4FE1\u606F\u9879")
193
256
  }).description("\u7FA4\u4FE1\u606F\u53D8\u91CF").collapse(),
194
- random: import_koishi3.Schema.object({
195
- variableName: import_koishi3.Schema.string().default("random").description("\u53D8\u91CF\u540D\u79F0"),
196
- min: import_koishi3.Schema.number().default(0).description("\u9ED8\u8BA4\u968F\u673A\u6570\u4E0B\u9650"),
197
- max: import_koishi3.Schema.number().default(100).description("\u9ED8\u8BA4\u968F\u673A\u6570\u4E0A\u9650")
257
+ random: import_koishi4.Schema.object({
258
+ variableName: import_koishi4.Schema.string().default("random").description("\u53D8\u91CF\u540D\u79F0"),
259
+ min: import_koishi4.Schema.number().default(0).description("\u9ED8\u8BA4\u968F\u673A\u6570\u4E0B\u9650"),
260
+ max: import_koishi4.Schema.number().default(100).description("\u9ED8\u8BA4\u968F\u673A\u6570\u4E0A\u9650")
198
261
  }).description("\u968F\u673A\u6570\u53D8\u91CF").collapse()
199
262
  }).default({
200
263
  userInfo: {
@@ -210,15 +273,16 @@ var VariablesSchema = import_koishi3.Schema.object({
210
273
  }).description("\u5176\u4ED6\u53D8\u91CF");
211
274
 
212
275
  // src/schema/index.ts
213
- var OtherSettingsSchema = import_koishi4.Schema.object({
214
- debugLogging: import_koishi4.Schema.boolean().default(false).description("\u8F93\u51FA\u8C03\u8BD5\u65E5\u5FD7")
276
+ var OtherSettingsSchema = import_koishi5.Schema.object({
277
+ debugLogging: import_koishi5.Schema.boolean().default(false).description("\u8F93\u51FA\u8C03\u8BD5\u65E5\u5FD7")
215
278
  }).description("\u5176\u4ED6\u8BBE\u7F6E");
216
279
  var name = "chatluna-toolbox";
217
280
  var inject = {
218
281
  required: ["chatluna"],
219
282
  optional: ["chatluna_character"]
220
283
  };
221
- var ConfigSchema = import_koishi4.Schema.intersect([
284
+ var ConfigSchema = import_koishi5.Schema.intersect([
285
+ BasicSettingsSchema,
222
286
  NativeToolsSchema,
223
287
  XmlToolsSchema,
224
288
  VariablesSchema,
@@ -302,10 +366,10 @@ async function sendDeleteMessage(params) {
302
366
  }
303
367
  }
304
368
  function createDeleteMessageTool(deps) {
305
- const { toolName, log } = deps;
369
+ const { toolName, description, log } = deps;
306
370
  const tool = {
307
371
  name: toolName || "delete_msg",
308
- description: "Deletes (recalls) a message by messageId only.",
372
+ description: description || DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION,
309
373
  schema: import_zod.z.object({
310
374
  messageId: import_zod.z.string().min(1, "messageId is required").describe("Specific message ID to delete.")
311
375
  }),
@@ -372,10 +436,10 @@ async function sendPoke(params) {
372
436
  }
373
437
  }
374
438
  function createPokeTool(deps) {
375
- const { toolName, log, protocol } = deps;
439
+ const { toolName, description, log, protocol } = deps;
376
440
  return new class extends import_tools.StructuredTool {
377
441
  name = toolName || "poke_user";
378
- description = "Poke (nudge) a specified user in a group or private conversation.";
442
+ description = description || DEFAULT_POKE_TOOL_DESCRIPTION;
379
443
  schema = import_zod2.z.object({
380
444
  userId: import_zod2.z.string().min(1, "userId is required").describe("The user ID to poke."),
381
445
  groupId: import_zod2.z.string().optional().describe("Optional: specify a different group ID.")
@@ -397,10 +461,10 @@ function createPokeTool(deps) {
397
461
  var import_zod3 = require("zod");
398
462
  var import_tools2 = require("@langchain/core/tools");
399
463
  function createSetGroupCardTool(deps) {
400
- const { toolName, log } = deps;
464
+ const { toolName, description, log } = deps;
401
465
  return new class extends import_tools2.StructuredTool {
402
466
  name = toolName || "set_group_card";
403
- description = "Update a group member nickname (group card).";
467
+ description = description || DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION;
404
468
  schema = import_zod3.z.object({
405
469
  groupId: import_zod3.z.string().optional().describe("Target group ID. Defaults to current session group."),
406
470
  userId: import_zod3.z.string().min(1, "userId is required").describe("Target member user ID."),
@@ -470,10 +534,10 @@ async function sendMsgEmoji(params) {
470
534
  }
471
535
  }
472
536
  function createSetMsgEmojiTool(deps) {
473
- const { toolName, log, protocol } = deps;
537
+ const { toolName, description, log, protocol } = deps;
474
538
  return new class extends import_tools3.StructuredTool {
475
539
  name = toolName || "set_msg_emoji";
476
- description = "React to a message with an emoji by messageId.";
540
+ description = description || DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION;
477
541
  schema = import_zod4.z.object({
478
542
  messageId: import_zod4.z.string().min(1, "message_id is required").describe("Target message ID."),
479
543
  emojiId: import_zod4.z.string().min(1, "emoji_id is required").describe("Emoji ID to send.")
@@ -500,10 +564,10 @@ var genders = {
500
564
  female: "2"
501
565
  };
502
566
  function createSetProfileTool(deps) {
503
- const { toolName, log, protocol } = deps;
567
+ const { toolName, description, log, protocol } = deps;
504
568
  return new class extends import_tools4.StructuredTool {
505
569
  name = toolName || "set_self_profile";
506
- description = "Update the bot's own QQ profile (nickname, signature, gender).";
570
+ description = description || DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION;
507
571
  schema = import_zod5.z.object({
508
572
  nickname: import_zod5.z.string().min(1, "nickname is required").describe("The new nickname for the bot."),
509
573
  signature: import_zod5.z.string().optional().describe("Optional: the new personal signature."),
@@ -533,6 +597,14 @@ function createSetProfileTool(deps) {
533
597
  }
534
598
 
535
599
  // src/features/native-tools/register.ts
600
+ function resolveToolName(value, fallback) {
601
+ const trimmedValue = value.trim();
602
+ return trimmedValue || fallback;
603
+ }
604
+ function resolveToolDescription(value, fallback) {
605
+ const trimmedValue = value.trim();
606
+ return trimmedValue || fallback;
607
+ }
536
608
  function resolveOneBotProtocol(config, log) {
537
609
  if (config.enableNapCatProtocol && config.enableLlbotProtocol) {
538
610
  log?.("warn", "NapCat \u4E0E LLBot \u534F\u8BAE\u540C\u65F6\u542F\u7528\uFF0C\u5C06\u4F18\u5148\u4F7F\u7528 LLBot\u3002");
@@ -545,366 +617,394 @@ function resolveOneBotProtocol(config, log) {
545
617
  }
546
618
  function registerNativeTools(deps) {
547
619
  const { ctx, config, plugin, protocol, log } = deps;
548
- if (config.enablePokeTool) {
549
- const toolName = String(config.pokeToolName || "poke_user").trim();
620
+ if (config.poke.enabled) {
621
+ const toolName = resolveToolName(config.poke.toolName, "poke_user");
622
+ const description = resolveToolDescription(
623
+ config.poke.description,
624
+ DEFAULT_POKE_TOOL_DESCRIPTION
625
+ );
550
626
  plugin.registerTool(toolName, {
551
627
  selector: () => true,
552
628
  authorization: (session) => session?.platform === "onebot",
553
- createTool: () => createPokeTool({ ctx, toolName, log, protocol })
629
+ createTool: () => createPokeTool({ ctx, toolName, description, log, protocol })
554
630
  });
555
631
  log?.("info", `\u6233\u4E00\u6233\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
556
632
  }
557
- if (config.enableSetSelfProfileTool) {
558
- const toolName = String(
559
- config.setSelfProfileToolName || "set_self_profile"
560
- ).trim();
633
+ if (config.setSelfProfile.enabled) {
634
+ const toolName = resolveToolName(
635
+ config.setSelfProfile.toolName,
636
+ "set_self_profile"
637
+ );
638
+ const description = resolveToolDescription(
639
+ config.setSelfProfile.description,
640
+ DEFAULT_SET_SELF_PROFILE_TOOL_DESCRIPTION
641
+ );
561
642
  plugin.registerTool(toolName, {
562
643
  selector: () => true,
563
644
  authorization: (session) => session?.platform === "onebot",
564
- createTool: () => createSetProfileTool({ ctx, toolName, log, protocol })
645
+ createTool: () => createSetProfileTool({ ctx, toolName, description, log, protocol })
565
646
  });
566
647
  log?.("info", `\u8BBE\u7F6E\u8D44\u6599\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
567
648
  }
568
- if (config.enableSetGroupCardTool) {
569
- const toolName = String(
570
- config.setGroupCardToolName || "set_group_card"
571
- ).trim();
649
+ if (config.setGroupCard.enabled) {
650
+ const toolName = resolveToolName(
651
+ config.setGroupCard.toolName,
652
+ "set_group_card"
653
+ );
654
+ const description = resolveToolDescription(
655
+ config.setGroupCard.description,
656
+ DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION
657
+ );
572
658
  plugin.registerTool(toolName, {
573
659
  selector: () => true,
574
660
  authorization: (session) => session?.platform === "onebot",
575
- createTool: () => createSetGroupCardTool({ ctx, toolName, log })
661
+ createTool: () => createSetGroupCardTool({ ctx, toolName, description, log })
576
662
  });
577
663
  log?.("info", `\u7FA4\u6635\u79F0\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
578
664
  }
579
- if (config.enableSetMsgEmojiTool) {
580
- const toolName = String(
581
- config.setMsgEmojiToolName || "set_msg_emoji"
582
- ).trim();
665
+ if (config.setMsgEmoji.enabled) {
666
+ const toolName = resolveToolName(
667
+ config.setMsgEmoji.toolName,
668
+ "set_msg_emoji"
669
+ );
670
+ const description = resolveToolDescription(
671
+ config.setMsgEmoji.description,
672
+ DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION
673
+ );
583
674
  plugin.registerTool(toolName, {
584
675
  selector: () => true,
585
676
  authorization: (session) => session?.platform === "onebot",
586
- createTool: () => createSetMsgEmojiTool({ toolName, log, protocol })
677
+ createTool: () => createSetMsgEmojiTool({ toolName, description, log, protocol })
587
678
  });
588
679
  log?.("info", `\u6D88\u606F\u8868\u60C5\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
589
680
  }
590
- if (config.enableDeleteMessageTool) {
591
- const toolName = String(
592
- config.deleteMessageToolName || "delete_msg"
593
- ).trim();
681
+ if (config.deleteMessage.enabled) {
682
+ const toolName = resolveToolName(
683
+ config.deleteMessage.toolName,
684
+ "delete_msg"
685
+ );
686
+ const description = resolveToolDescription(
687
+ config.deleteMessage.description,
688
+ DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION
689
+ );
594
690
  plugin.registerTool(toolName, {
595
691
  selector: () => true,
596
692
  authorization: (session) => session?.platform === "onebot",
597
- createTool: () => createDeleteMessageTool({ toolName, log })
693
+ createTool: () => createDeleteMessageTool({ toolName, description, log })
598
694
  });
599
695
  log?.("info", `\u5220\u9664\u6D88\u606F\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
600
696
  }
601
697
  }
602
698
 
603
- // src/features/xml-tools/interceptor.ts
604
- function createXmlInterceptor(deps) {
605
- const { ctx, config, log, onResponse } = deps;
606
- const sessionMap = /* @__PURE__ */ new Map();
607
- let currentGuildId = null;
608
- let lastSession = null;
609
- const pendingSessions = [];
610
- let responseSeq = 0;
611
- const processedResponses = /* @__PURE__ */ new Set();
612
- let monitorHandle = null;
613
- let fastRetryHandle = null;
614
- let startupHandle = null;
615
- const responseRetryHandles = /* @__PURE__ */ new Map();
616
- let activeService = null;
617
- let activeLogger = null;
618
- let originalDebug = null;
619
- let collectorBound = false;
620
- const restore = () => {
621
- if (activeLogger && originalDebug) {
622
- activeLogger.debug = originalDebug;
623
- }
624
- activeLogger = null;
625
- originalDebug = null;
626
- };
627
- const isActive = () => {
628
- const characterService = ctx.chatluna_character;
629
- const debugFn = characterService?.logger?.debug;
630
- return Boolean(debugFn?.[RAW_INTERCEPTOR_TAG]);
631
- };
632
- const resolveSession = () => {
633
- while (pendingSessions.length > 100) pendingSessions.shift();
634
- const now = Date.now();
635
- while (pendingSessions.length > 0 && now - pendingSessions[0].timestamp > 12e3) {
636
- pendingSessions.shift();
637
- }
638
- if (pendingSessions.length === 0) {
639
- return (currentGuildId ? sessionMap.get(currentGuildId) : null) || lastSession || null;
640
- }
641
- const contextKeys = /* @__PURE__ */ new Set();
642
- for (let i = 0; i < pendingSessions.length; i++) {
643
- contextKeys.add(pendingSessions[i].key || "__null__");
699
+ // src/features/xml-tools/parser.ts
700
+ function parseSelfClosingXmlTags(text, tagName) {
701
+ const tags = Array.from(
702
+ text.matchAll(new RegExp(`<${tagName}\\b([^>]*)\\/>`, "gi"))
703
+ );
704
+ if (!tags.length) return [];
705
+ return tags.map((tag) => {
706
+ const attrText = String(tag[1] || "");
707
+ const attrs = {};
708
+ for (const pair of attrText.matchAll(/([a-zA-Z_][\w-]*)="([^"]*)"/g)) {
709
+ attrs[pair[1]] = pair[2];
644
710
  }
645
- let resolved = pendingSessions[pendingSessions.length - 1];
646
- if (currentGuildId) {
647
- for (let i = pendingSessions.length - 1; i >= 0; i--) {
648
- if (pendingSessions[i].key === currentGuildId) {
649
- resolved = pendingSessions[i];
650
- break;
711
+ return attrs;
712
+ });
713
+ }
714
+
715
+ // src/features/xml-tools/processor.ts
716
+ function createXmlProcessor(deps) {
717
+ const {
718
+ config,
719
+ protocol,
720
+ log,
721
+ sendPoke: runPoke = sendPoke,
722
+ sendMsgEmoji: runEmoji = sendMsgEmoji,
723
+ sendDeleteMessage: runDelete = sendDeleteMessage
724
+ } = deps;
725
+ return async ({ response, session }) => {
726
+ const content = String(response || "").trim();
727
+ if (!content) return false;
728
+ const pokeTags = parseSelfClosingXmlTags(content, "poke");
729
+ const emojiTags = parseSelfClosingXmlTags(content, "emoji");
730
+ const deleteTags = parseSelfClosingXmlTags(content, "delete");
731
+ let handled = false;
732
+ if (config.enablePokeXmlTool && pokeTags.length > 0) {
733
+ if (!session) {
734
+ log?.("warn", "\u68C0\u6D4B\u5230\u6233\u4E00\u6233\u6807\u8BB0\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587");
735
+ } else {
736
+ const userIds = pokeTags.map((attrs) => String(attrs.id || "").trim()).filter(Boolean);
737
+ if (userIds.length > 0) handled = true;
738
+ for (const userId of userIds) {
739
+ try {
740
+ await runPoke({ session, userId, protocol, log });
741
+ } catch (error) {
742
+ log?.("warn", "XML \u89E6\u53D1 poke \u5931\u8D25", error);
743
+ }
651
744
  }
652
745
  }
653
746
  }
654
- pendingSessions.length = 0;
655
- if (contextKeys.size > 1 && config.debugLogging) {
656
- log?.("warn", "\u68C0\u6D4B\u5230\u591A\u4E2A\u4F1A\u8BDD\u4E0A\u4E0B\u6587\uFF0C\u5DF2\u4F7F\u7528\u6700\u8FD1\u4F1A\u8BDD\u7EE7\u7EED\u6267\u884C XML", {
657
- contextCount: contextKeys.size,
658
- preferredGuildId: currentGuildId,
659
- resolvedGuildId: resolved.key
660
- });
661
- }
662
- return resolved.key ? sessionMap.get(resolved.key) || resolved.session : resolved.session;
663
- };
664
- const markProcessed = (responseId) => {
665
- processedResponses.add(responseId);
666
- if (processedResponses.size > 100) {
667
- const first = processedResponses.values().next().value;
668
- if (first) processedResponses.delete(first);
669
- }
670
- };
671
- const runResponse = (responseId, response, session) => {
672
- const handled = onResponse(response, session);
673
- if (handled) {
674
- markProcessed(responseId);
675
- const retryHandle = responseRetryHandles.get(responseId);
676
- if (retryHandle) {
677
- retryHandle();
678
- responseRetryHandles.delete(responseId);
747
+ if (config.enableEmojiXmlTool && emojiTags.length > 0) {
748
+ if (!session) {
749
+ log?.("warn", "\u68C0\u6D4B\u5230\u8868\u60C5\u6807\u8BB0\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587");
750
+ } else {
751
+ const items = emojiTags.map((attrs) => ({
752
+ messageId: String(attrs.message_id || "").trim(),
753
+ emojiId: String(attrs.emoji_id || "").trim()
754
+ })).filter((item) => item.messageId && item.emojiId);
755
+ if (items.length > 0) handled = true;
756
+ for (const item of items) {
757
+ try {
758
+ await runEmoji({
759
+ session,
760
+ messageId: item.messageId,
761
+ emojiId: item.emojiId,
762
+ protocol,
763
+ log
764
+ });
765
+ } catch (error) {
766
+ log?.("warn", "XML \u89E6\u53D1\u8868\u60C5\u5931\u8D25", error);
767
+ }
768
+ }
679
769
  }
680
770
  }
681
- return handled;
682
- };
683
- const retryResponse = (responseId, response) => {
684
- if (responseRetryHandles.has(responseId) || processedResponses.has(responseId))
685
- return;
686
- const handle = ctx.setTimeout(() => {
687
- responseRetryHandles.delete(responseId);
688
- if (processedResponses.has(responseId)) return;
689
- const session = resolveSession();
771
+ if (config.enableDeleteXmlTool && deleteTags.length > 0) {
690
772
  if (!session) {
691
- if (config.debugLogging) {
692
- log?.("warn", "\u62E6\u622A\u5230\u539F\u59CB\u8F93\u51FA\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587\uFF0CXML \u5DE5\u5177\u4E0D\u4F1A\u6267\u884C", {
693
- length: response.length
694
- });
773
+ log?.("warn", "\u68C0\u6D4B\u5230\u64A4\u56DE\u6807\u8BB0\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587");
774
+ } else {
775
+ const messageIds = deleteTags.map((attrs) => String(attrs.message_id || "").trim()).filter(Boolean);
776
+ if (messageIds.length > 0) handled = true;
777
+ for (const messageId of messageIds) {
778
+ try {
779
+ await runDelete({ session, messageId, log });
780
+ } catch (error) {
781
+ log?.("warn", "XML \u89E6\u53D1\u64A4\u56DE\u5931\u8D25", error);
782
+ }
695
783
  }
696
- runResponse(responseId, response, null);
697
- return;
698
784
  }
699
- runResponse(responseId, response, session);
700
- }, 200);
701
- responseRetryHandles.set(responseId, handle);
702
- };
703
- const attach = () => {
704
- const characterService = ctx.chatluna_character;
705
- if (!characterService) return false;
706
- if (activeService !== characterService) {
707
- activeService = characterService;
708
- collectorBound = false;
709
- }
710
- if (!collectorBound && typeof characterService.collect === "function") {
711
- characterService.collect(async (session) => {
712
- const guildId = session?.guildId || session?.channelId || session?.userId || null;
713
- currentGuildId = guildId;
714
- if (guildId) sessionMap.set(guildId, session);
715
- lastSession = session;
716
- pendingSessions.push({ key: guildId, session, timestamp: Date.now() });
717
- });
718
- collectorBound = true;
719
785
  }
720
- const loggerService = characterService.logger;
721
- if (!loggerService || typeof loggerService.debug !== "function")
722
- return false;
723
- const tagged = loggerService.debug;
724
- if (!tagged[RAW_INTERCEPTOR_TAG]) {
725
- restore();
726
- const raw = loggerService.debug.bind(loggerService);
727
- const wrapped = (...args) => {
728
- raw(...args);
729
- const message = args[0];
730
- if (typeof message !== "string") return;
731
- const prefix = ["model response: ", "model response:\n"].find(
732
- (item) => message.startsWith(item)
733
- );
734
- if (!prefix) return;
735
- const response = message.substring(prefix.length);
736
- if (!response) return;
737
- const responseId = `${Date.now()}:${responseSeq++}`;
738
- const session = resolveSession();
739
- if (!session) {
740
- retryResponse(responseId, response);
741
- return;
786
+ return handled;
787
+ };
788
+ }
789
+
790
+ // src/features/xml-tools/temp-runtime.ts
791
+ var GET_TEMP_TAG = /* @__PURE__ */ Symbol.for("chatlunaToolboxXmlGetTempRuntime");
792
+ var GET_TEMP_ORIGINAL = /* @__PURE__ */ Symbol.for("chatlunaToolboxXmlOriginalGetTemp");
793
+ var GET_TEMP_LISTENERS = /* @__PURE__ */ Symbol.for("chatlunaToolboxXmlGetTempListeners");
794
+ var PUSH_DISPATCHER = /* @__PURE__ */ Symbol.for("chatlunaToolboxXmlPushDispatcher");
795
+ function getMessageType(message) {
796
+ if (!message) return "";
797
+ if (typeof message._getType === "function") {
798
+ return String(message._getType() || "").trim().toLowerCase();
799
+ }
800
+ return String(message.type || message.role || "").trim().toLowerCase();
801
+ }
802
+ function isAssistantMessage(message) {
803
+ const type = getMessageType(message);
804
+ return type === "ai" || type === "assistant";
805
+ }
806
+ function extractText(value) {
807
+ if (typeof value === "string") return value;
808
+ if (value == null) return "";
809
+ if (Array.isArray(value)) {
810
+ return value.map((item) => extractText(item)).join("");
811
+ }
812
+ if (typeof value !== "object") return "";
813
+ const record = value;
814
+ if (typeof record.text === "string") return record.text;
815
+ if (record.content !== void 0 && record.content !== value) {
816
+ return extractText(record.content);
817
+ }
818
+ if (Array.isArray(record.children)) return extractText(record.children);
819
+ if (typeof record.attrs === "object" && record.attrs) {
820
+ const attrs = record.attrs;
821
+ if (typeof attrs.content === "string") return attrs.content;
822
+ if (typeof attrs.text === "string") return attrs.text;
823
+ }
824
+ return "";
825
+ }
826
+ function getResponseText(message) {
827
+ if (!isAssistantMessage(message)) return "";
828
+ return extractText(message?.content ?? message?.text).trim();
829
+ }
830
+ function getDispatcher(messages) {
831
+ return messages[PUSH_DISPATCHER] ?? null;
832
+ }
833
+ function setDispatcher(messages, dispatcher) {
834
+ const record = messages;
835
+ if (!dispatcher) {
836
+ delete record[PUSH_DISPATCHER];
837
+ return;
838
+ }
839
+ Object.defineProperty(record, PUSH_DISPATCHER, {
840
+ value: dispatcher,
841
+ configurable: true,
842
+ enumerable: false,
843
+ writable: true
844
+ });
845
+ }
846
+ function attachDispatcher(messages, log) {
847
+ const existing = getDispatcher(messages);
848
+ if (existing) return existing;
849
+ const listeners = /* @__PURE__ */ new Set();
850
+ const processedMessages = /* @__PURE__ */ new WeakSet();
851
+ const originalPush = messages.push;
852
+ const patchedPush = function patchedPush2(...items) {
853
+ const result = originalPush.apply(this, items);
854
+ for (const item of items) {
855
+ if (!item || typeof item !== "object") continue;
856
+ const message = item;
857
+ if (!isAssistantMessage(message)) continue;
858
+ if (processedMessages.has(item)) continue;
859
+ const response = getResponseText(message);
860
+ if (!response) continue;
861
+ processedMessages.add(item);
862
+ for (const listener of Array.from(listeners)) {
863
+ try {
864
+ listener(message);
865
+ } catch (error) {
866
+ log?.("warn", "\u5904\u7406 XML completionMessages \u76D1\u542C\u5668\u5931\u8D25", error);
742
867
  }
743
- runResponse(responseId, response, session);
744
- };
745
- wrapped[RAW_INTERCEPTOR_TAG] = true;
746
- loggerService.debug = wrapped;
747
- activeLogger = loggerService;
748
- originalDebug = raw;
868
+ }
749
869
  }
750
- return true;
870
+ return result;
751
871
  };
752
- const stopFastRetry = () => {
753
- if (!fastRetryHandle) return;
754
- fastRetryHandle();
755
- fastRetryHandle = null;
872
+ const dispatcher = {
873
+ messages,
874
+ originalPush,
875
+ patchedPush,
876
+ listeners,
877
+ processedMessages
756
878
  };
757
- const startFastRetry = () => {
758
- if (fastRetryHandle) return;
759
- fastRetryHandle = ctx.setInterval(() => {
760
- if (isActive()) {
761
- stopFastRetry();
762
- return;
763
- }
764
- const ready = attach();
765
- if (ready) {
766
- log?.("info", "\u539F\u59CB\u8F93\u51FA\u62E6\u622A\u5DF2\u6062\u590D");
767
- stopFastRetry();
879
+ messages.push = patchedPush;
880
+ setDispatcher(messages, dispatcher);
881
+ return dispatcher;
882
+ }
883
+ function restoreDispatcher(dispatcher) {
884
+ if (dispatcher.messages.push === dispatcher.patchedPush) {
885
+ dispatcher.messages.push = dispatcher.originalPush;
886
+ }
887
+ setDispatcher(dispatcher.messages, null);
888
+ }
889
+ function registerGetTempListener(service, listener) {
890
+ const getTemp = service.getTemp;
891
+ if (typeof getTemp !== "function") return null;
892
+ const serviceRecord = service;
893
+ let listeners = serviceRecord[GET_TEMP_LISTENERS];
894
+ if (!listeners) {
895
+ listeners = /* @__PURE__ */ new Set();
896
+ serviceRecord[GET_TEMP_LISTENERS] = listeners;
897
+ }
898
+ if (!serviceRecord[GET_TEMP_TAG]) {
899
+ Object.defineProperty(serviceRecord, GET_TEMP_ORIGINAL, {
900
+ value: getTemp,
901
+ configurable: true,
902
+ enumerable: false,
903
+ writable: true
904
+ });
905
+ service.getTemp = async (...args) => {
906
+ const originalGetTemp = serviceRecord[GET_TEMP_ORIGINAL];
907
+ const temp = await originalGetTemp?.apply(
908
+ service,
909
+ args
910
+ );
911
+ const activeListeners = serviceRecord[GET_TEMP_LISTENERS];
912
+ const session = args[0] && typeof args[0] === "object" ? args[0] : null;
913
+ if (temp && activeListeners?.size) {
914
+ for (const handler of Array.from(activeListeners)) {
915
+ handler(temp, session);
916
+ }
768
917
  }
769
- }, 3e3);
918
+ return temp;
919
+ };
920
+ serviceRecord[GET_TEMP_TAG] = true;
921
+ }
922
+ listeners.add(listener);
923
+ return () => {
924
+ const currentListeners = serviceRecord[GET_TEMP_LISTENERS];
925
+ currentListeners?.delete(listener);
926
+ if (currentListeners?.size) return;
927
+ const originalGetTemp = serviceRecord[GET_TEMP_ORIGINAL];
928
+ if (originalGetTemp) service.getTemp = originalGetTemp;
929
+ delete serviceRecord[GET_TEMP_ORIGINAL];
930
+ delete serviceRecord[GET_TEMP_TAG];
931
+ delete serviceRecord[GET_TEMP_LISTENERS];
770
932
  };
771
- const ensureActive = () => {
772
- if (isActive()) {
773
- stopFastRetry();
774
- return;
775
- }
776
- const ready = attach();
777
- if (!ready) {
778
- startFastRetry();
779
- }
933
+ }
934
+ function createCharacterTempXmlRuntime(params) {
935
+ const { getCharacterService, processModelResponse, log } = params;
936
+ let attachedDispatchers = [];
937
+ let stopListening = null;
938
+ const compactAttachedDispatchers = () => {
939
+ attachedDispatchers = attachedDispatchers.filter(
940
+ (entry) => Boolean(entry.ref.deref())
941
+ );
942
+ };
943
+ const hasAttachedListener = (dispatcher) => {
944
+ compactAttachedDispatchers();
945
+ return attachedDispatchers.some(
946
+ (entry) => entry.ref.deref() === dispatcher
947
+ );
780
948
  };
781
- const startMonitor = () => {
782
- if (monitorHandle) return;
783
- monitorHandle = ctx.setInterval(() => {
784
- ensureActive();
785
- }, 5e3);
949
+ const detachDispatcherListener = (entry) => {
950
+ const dispatcher = entry.ref.deref();
951
+ if (!dispatcher) return;
952
+ dispatcher.listeners.delete(entry.listener);
953
+ if (dispatcher.listeners.size === 0) restoreDispatcher(dispatcher);
786
954
  };
787
- const stopMonitor = () => {
788
- if (!monitorHandle) return;
789
- monitorHandle();
790
- monitorHandle = null;
955
+ const handleTemp = (temp, session) => {
956
+ const messages = temp.completionMessages;
957
+ if (!Array.isArray(messages) || typeof messages.push !== "function") return;
958
+ const dispatcher = attachDispatcher(messages, log);
959
+ if (hasAttachedListener(dispatcher)) return;
960
+ const listener = (message) => {
961
+ const response = getResponseText(message);
962
+ if (!response) return;
963
+ void processModelResponse({ response, session }).catch((error) => {
964
+ log?.("warn", "\u5904\u7406 XML \u6A21\u578B\u54CD\u5E94\u5931\u8D25", error);
965
+ });
966
+ };
967
+ dispatcher.listeners.add(listener);
968
+ attachedDispatchers.push({ ref: new WeakRef(dispatcher), listener });
791
969
  };
792
970
  return {
793
971
  start: () => {
794
- const delay = 3e3;
795
- if (startupHandle) return;
796
- startupHandle = ctx.setTimeout(() => {
797
- startupHandle = null;
798
- const ready = attach();
799
- if (ready) {
800
- log?.("info", "\u5DF2\u542F\u7528\u539F\u59CB\u8F93\u51FA\u62E6\u622A\u6A21\u5F0F");
801
- } else {
802
- log?.("warn", "chatluna_character \u670D\u52A1\u4E0D\u53EF\u7528\uFF0C\u5C06\u6BCF3\u79D2\u91CD\u8BD5\u4E00\u6B21");
803
- startFastRetry();
972
+ if (stopListening) return true;
973
+ const service = getCharacterService();
974
+ if (!service) return false;
975
+ const detach = registerGetTempListener(service, handleTemp);
976
+ if (!detach) return false;
977
+ stopListening = () => {
978
+ compactAttachedDispatchers();
979
+ for (const entry of attachedDispatchers) {
980
+ detachDispatcherListener(entry);
804
981
  }
805
- startMonitor();
806
- }, delay);
982
+ attachedDispatchers = [];
983
+ detach();
984
+ stopListening = null;
985
+ };
986
+ return true;
807
987
  },
808
988
  stop: () => {
809
- if (startupHandle) {
810
- startupHandle();
811
- startupHandle = null;
812
- }
813
- stopFastRetry();
814
- stopMonitor();
815
- for (const handle of responseRetryHandles.values()) handle();
816
- responseRetryHandles.clear();
817
- processedResponses.clear();
818
- restore();
819
- sessionMap.clear();
820
- pendingSessions.length = 0;
821
- currentGuildId = null;
822
- lastSession = null;
823
- activeService = null;
824
- }
825
- };
826
- }
827
-
828
- // src/features/xml-tools/parser.ts
829
- function unique(values) {
830
- return Array.from(new Set(values.map((item) => item.trim()).filter(Boolean)));
831
- }
832
- function parseXmlActions(response) {
833
- const pokeMatches = Array.from(response.matchAll(/<poke\s+id="([^"]+)"\s*\/>/gi));
834
- const emojiMatches = Array.from(
835
- response.matchAll(/<emoji\s+message_id="([^"]+)"\s+emoji_id="([^"]+)"\s*\/>/gi)
836
- );
837
- const deleteMatches = Array.from(response.matchAll(/<delete\s+message_id="([^"]+)"\s*\/?>/gi));
838
- return {
839
- pokeUserIds: unique(pokeMatches.map((match) => String(match[1] || ""))),
840
- emojis: emojiMatches.map((match) => ({
841
- messageId: String(match[1] || "").trim(),
842
- emojiId: String(match[2] || "").trim()
843
- })).filter((item) => item.messageId && item.emojiId),
844
- deleteMessageIds: unique(deleteMatches.map((match) => String(match[1] || "")))
989
+ stopListening?.();
990
+ },
991
+ isActive: () => Boolean(stopListening)
845
992
  };
846
993
  }
847
994
 
848
995
  // src/features/xml-tools/register.ts
849
996
  function registerXmlTools(deps) {
850
997
  const { ctx, config, protocol, log } = deps;
851
- const interceptor = createXmlInterceptor({
852
- ctx,
853
- config,
854
- log,
855
- onResponse: (response, session) => {
856
- const actions = parseXmlActions(response);
857
- let handled = false;
858
- if (config.enablePokeXmlTool && actions.pokeUserIds.length > 0) {
859
- if (!session) {
860
- log?.("warn", "\u68C0\u6D4B\u5230\u6233\u4E00\u6233\u6807\u8BB0\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587");
861
- } else {
862
- handled = true;
863
- for (const userId of actions.pokeUserIds) {
864
- void sendPoke({ session, userId, protocol, log }).catch((error) => {
865
- log?.("warn", "XML \u89E6\u53D1 poke \u5931\u8D25", error);
866
- });
867
- }
868
- }
869
- }
870
- if (config.enableEmojiXmlTool && actions.emojis.length > 0) {
871
- if (!session) {
872
- log?.("warn", "\u68C0\u6D4B\u5230\u8868\u60C5\u6807\u8BB0\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587");
873
- } else {
874
- handled = true;
875
- for (const item of actions.emojis) {
876
- void sendMsgEmoji({
877
- session,
878
- messageId: item.messageId,
879
- emojiId: item.emojiId,
880
- protocol,
881
- log
882
- }).catch((error) => {
883
- log?.("warn", "XML \u89E6\u53D1\u8868\u60C5\u5931\u8D25", error);
884
- });
885
- }
886
- }
887
- }
888
- if (config.enableDeleteXmlTool && actions.deleteMessageIds.length > 0) {
889
- if (!session) {
890
- log?.("warn", "\u68C0\u6D4B\u5230\u64A4\u56DE\u6807\u8BB0\u4F46\u7F3A\u5C11\u4F1A\u8BDD\u4E0A\u4E0B\u6587");
891
- } else {
892
- handled = true;
893
- for (const messageId of actions.deleteMessageIds) {
894
- void sendDeleteMessage({ session, messageId, log }).catch(
895
- (error) => {
896
- log?.("warn", "XML \u89E6\u53D1\u64A4\u56DE\u5931\u8D25", error);
897
- }
898
- );
899
- }
900
- }
901
- }
902
- return handled;
903
- }
998
+ const processor = createXmlProcessor({ config, protocol, log });
999
+ const runtime = createCharacterTempXmlRuntime({
1000
+ getCharacterService: () => ctx.chatluna_character,
1001
+ processModelResponse: processor,
1002
+ log
904
1003
  });
905
1004
  return {
906
- start: () => interceptor.start(),
907
- stop: () => interceptor.stop()
1005
+ start: () => runtime.start(),
1006
+ stop: () => runtime.stop(),
1007
+ isActive: () => runtime.isActive()
908
1008
  };
909
1009
  }
910
1010
 
@@ -1509,22 +1609,35 @@ function apply(ctx, config) {
1509
1609
  };
1510
1610
  const log = createLogger(ctx, config);
1511
1611
  let xmlRuntime = null;
1612
+ let characterCtx = null;
1512
1613
  const initializeServices = async () => {
1513
1614
  log("info", "toolbox \u521D\u59CB\u5316\u5F00\u59CB");
1514
1615
  registerVariables({ ctx, config, log });
1515
1616
  const protocol = resolveOneBotProtocol(config, log);
1516
1617
  registerNativeTools({ ctx, config, plugin, protocol, log });
1517
- if (config.enablePokeXmlTool || config.enableEmojiXmlTool || config.enableDeleteXmlTool) {
1518
- xmlRuntime = registerXmlTools({ ctx, config, protocol, log });
1519
- xmlRuntime.start();
1618
+ xmlRuntime = registerXmlTools({ ctx, config, protocol, log });
1619
+ if (characterCtx && xmlRuntime.start()) {
1520
1620
  log("info", "XML \u5DE5\u5177\u5DF2\u542F\u7528");
1521
1621
  }
1522
1622
  log("info", "toolbox \u521D\u59CB\u5316\u5B8C\u6210");
1523
1623
  };
1524
1624
  const dispose = () => {
1625
+ characterCtx = null;
1525
1626
  xmlRuntime?.stop();
1526
1627
  xmlRuntime = null;
1527
1628
  };
1629
+ if (config.enablePokeXmlTool || config.enableEmojiXmlTool || config.enableDeleteXmlTool) {
1630
+ ctx.inject(["chatluna_character"], (innerCtx) => {
1631
+ characterCtx = innerCtx;
1632
+ if (!xmlRuntime) return;
1633
+ const started = xmlRuntime.start();
1634
+ if (started) log("info", "XML \u5DE5\u5177\u5DF2\u542F\u7528");
1635
+ innerCtx.on("dispose", () => {
1636
+ if (characterCtx === innerCtx) characterCtx = null;
1637
+ xmlRuntime?.stop();
1638
+ });
1639
+ });
1640
+ }
1528
1641
  ctx.on("dispose", dispose);
1529
1642
  if (ctx.root.lifecycle.isActive) {
1530
1643
  void initializeServices();
@@ -1536,6 +1649,7 @@ function apply(ctx, config) {
1536
1649
  }
1537
1650
  // Annotate the CommonJS export names for ESM import in node:
1538
1651
  0 && (module.exports = {
1652
+ BasicSettingsSchema,
1539
1653
  Config,
1540
1654
  ConfigSchema,
1541
1655
  DEFAULT_GROUP_INFO_ITEMS,
@@ -1547,6 +1661,7 @@ function apply(ctx, config) {
1547
1661
  apply,
1548
1662
  callOneBotAPI,
1549
1663
  createBotInfoProvider,
1664
+ createCharacterTempXmlRuntime,
1550
1665
  createDeleteMessageTool,
1551
1666
  createGroupInfoProvider,
1552
1667
  createLogger,
@@ -1556,12 +1671,12 @@ function apply(ctx, config) {
1556
1671
  createSetMsgEmojiTool,
1557
1672
  createSetProfileTool,
1558
1673
  createUserInfoProvider,
1559
- createXmlInterceptor,
1674
+ createXmlProcessor,
1560
1675
  ensureOneBotSession,
1561
1676
  getSession,
1562
1677
  inject,
1563
1678
  name,
1564
- parseXmlActions,
1679
+ parseSelfClosingXmlTags,
1565
1680
  registerNativeTools,
1566
1681
  registerVariables,
1567
1682
  registerXmlTools,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "koishi-plugin-chatluna-toolbox",
3
3
  "description": "为 ChatLuna 提供更多原生工具、XML 工具与变量。",
4
- "version": "0.0.5",
4
+ "version": "0.0.7",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
7
7
  "files": [