koishi-plugin-chatluna-toolbox 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client/ToolboxDetailsLoader.vue +20 -0
- package/client/constants.ts +19 -0
- package/client/index.ts +15 -0
- package/dist/index.js +264 -0
- package/dist/style.css +1 -0
- package/lib/index.js +436 -225
- package/package.json +17 -5
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
Toolbox 详情加载器
|
|
3
|
+
根据当前插件名称决定是否显示共享导航组件
|
|
4
|
+
-->
|
|
5
|
+
<template>
|
|
6
|
+
<SharedNav v-if="isOwn" :sections="navSections" />
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script setup lang="ts">
|
|
10
|
+
import { ComputedRef, computed, inject } from "vue";
|
|
11
|
+
import { SharedNav } from "shared-nav";
|
|
12
|
+
import { NAV_SECTIONS, PLUGIN_CANDIDATE_NAMES } from "./constants";
|
|
13
|
+
|
|
14
|
+
const pluginName = inject<ComputedRef<string>>("plugin:name");
|
|
15
|
+
const navSections = NAV_SECTIONS;
|
|
16
|
+
const isOwn = computed(() => {
|
|
17
|
+
const name = pluginName?.value || "";
|
|
18
|
+
return PLUGIN_CANDIDATE_NAMES.includes(name);
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 前端常量定义
|
|
3
|
+
* 包含导航分组和插件候选名称
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { SharedNavSection } from "shared-nav";
|
|
7
|
+
|
|
8
|
+
export const NAV_SECTIONS: SharedNavSection[] = [
|
|
9
|
+
{ title: "基础设置", key: "basic" },
|
|
10
|
+
{ title: "原生工具", key: "nativeTools" },
|
|
11
|
+
{ title: "XML 工具", key: "xmlTools" },
|
|
12
|
+
{ title: "其他变量", key: "variables" },
|
|
13
|
+
{ title: "其他设置", key: "other" },
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export const PLUGIN_CANDIDATE_NAMES = [
|
|
17
|
+
"chatluna-toolbox",
|
|
18
|
+
"koishi-plugin-chatluna-toolbox",
|
|
19
|
+
];
|
package/client/index.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 前端入口
|
|
3
|
+
* 注册 Koishi 控制台插件详情扩展
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { Context } from "@koishijs/client";
|
|
7
|
+
import ToolboxDetailsLoader from "./ToolboxDetailsLoader.vue";
|
|
8
|
+
|
|
9
|
+
export default (ctx: Context) => {
|
|
10
|
+
ctx.slot({
|
|
11
|
+
type: "plugin-details",
|
|
12
|
+
component: ToolboxDetailsLoader,
|
|
13
|
+
order: -999,
|
|
14
|
+
});
|
|
15
|
+
};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { openBlock as y, createElementBlock as _, createElementVNode as w, defineComponent as b, Fragment as E, renderList as N, normalizeClass as m, toDisplayString as z, reactive as I, computed as f, onUnmounted as L, ref as T, onMounted as B, normalizeStyle as A, unref as k, createVNode as x, withModifiers as D, inject as K, createBlock as X, createCommentVNode as O } from "vue";
|
|
2
|
+
const M = (s, o) => {
|
|
3
|
+
const r = s.__vccOpts || s;
|
|
4
|
+
for (const [c, t] of o)
|
|
5
|
+
r[c] = t;
|
|
6
|
+
return r;
|
|
7
|
+
}, V = {}, Y = {
|
|
8
|
+
viewBox: "0 0 1024 1024",
|
|
9
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
10
|
+
width: "20",
|
|
11
|
+
height: "20"
|
|
12
|
+
};
|
|
13
|
+
function q(s, o) {
|
|
14
|
+
return y(), _("svg", Y, [...o[0] || (o[0] = [
|
|
15
|
+
w("path", {
|
|
16
|
+
d: "M288 224c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zm320 0c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zM288 512c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zm320 0c0-35.3 28.7-64 64-64s64 28.7 64 64-28.7 64-64 64-64-28.7-64-64zM352 864c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm320 0c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64z",
|
|
17
|
+
fill: "currentColor"
|
|
18
|
+
}, null, -1)
|
|
19
|
+
])]);
|
|
20
|
+
}
|
|
21
|
+
const P = /* @__PURE__ */ M(V, [["render", q]]), W = {}, j = {
|
|
22
|
+
viewBox: "0 0 1024 1024",
|
|
23
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
24
|
+
width: "20",
|
|
25
|
+
height: "20"
|
|
26
|
+
};
|
|
27
|
+
function U(s, o) {
|
|
28
|
+
return y(), _("svg", j, [...o[0] || (o[0] = [
|
|
29
|
+
w("path", {
|
|
30
|
+
d: "M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.712a29.12 29.12 0 0 0 0-41.728 30.592 30.592 0 0 0-42.752 0z",
|
|
31
|
+
fill: "currentColor"
|
|
32
|
+
}, null, -1)
|
|
33
|
+
])]);
|
|
34
|
+
}
|
|
35
|
+
const F = /* @__PURE__ */ M(W, [["render", U]]), G = ["onClick"], H = /* @__PURE__ */ b({
|
|
36
|
+
__name: "NavSection",
|
|
37
|
+
props: {
|
|
38
|
+
sections: {},
|
|
39
|
+
activeKey: {}
|
|
40
|
+
},
|
|
41
|
+
emits: ["select"],
|
|
42
|
+
setup(s) {
|
|
43
|
+
return (o, r) => (y(!0), _(E, null, N(s.sections, (c) => (y(), _("div", {
|
|
44
|
+
key: c.key,
|
|
45
|
+
class: m([o.$style.item, s.activeKey === c.key ? o.$style.active : ""]),
|
|
46
|
+
onClick: (t) => o.$emit("select", c)
|
|
47
|
+
}, z(c.title), 11, G))), 128));
|
|
48
|
+
}
|
|
49
|
+
}), J = "_item_1m2kp_1", Q = "_active_1m2kp_16", Z = {
|
|
50
|
+
item: J,
|
|
51
|
+
active: Q
|
|
52
|
+
}, tt = {
|
|
53
|
+
$style: Z
|
|
54
|
+
}, et = /* @__PURE__ */ M(H, [["__cssModules", tt]]);
|
|
55
|
+
function R(s) {
|
|
56
|
+
return s instanceof TouchEvent ? {
|
|
57
|
+
x: s.touches[0].clientX,
|
|
58
|
+
y: s.touches[0].clientY
|
|
59
|
+
} : {
|
|
60
|
+
x: s.clientX,
|
|
61
|
+
y: s.clientY
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function ot(s = {}) {
|
|
65
|
+
const {
|
|
66
|
+
initialTop: o = 100,
|
|
67
|
+
initialRight: r = 20,
|
|
68
|
+
boundarySelector: c = ".plugin-view"
|
|
69
|
+
} = s, t = I({
|
|
70
|
+
isDragging: !1,
|
|
71
|
+
top: o,
|
|
72
|
+
right: r,
|
|
73
|
+
startTop: 0,
|
|
74
|
+
startRight: 0,
|
|
75
|
+
startX: 0,
|
|
76
|
+
startY: 0,
|
|
77
|
+
width: 0,
|
|
78
|
+
height: 0
|
|
79
|
+
}), g = f(() => ({
|
|
80
|
+
top: `${t.top}px`,
|
|
81
|
+
right: `${t.right}px`
|
|
82
|
+
})), i = (d) => {
|
|
83
|
+
var C;
|
|
84
|
+
if (!t.isDragging)
|
|
85
|
+
return;
|
|
86
|
+
const a = R(d), l = t.startTop + (a.y - t.startY), e = t.startRight - (a.x - t.startX), n = (C = document.querySelector(c)) == null ? void 0 : C.getBoundingClientRect();
|
|
87
|
+
let h = 0, v = window.innerHeight - t.height, S = 0, $ = window.innerWidth - t.width;
|
|
88
|
+
n && (h = n.top, v = n.bottom - t.height, S = window.innerWidth - n.right, $ = window.innerWidth - n.left - t.width), t.top = Math.max(h, Math.min(v, l)), t.right = Math.max(S, Math.min($, e));
|
|
89
|
+
}, p = (d, a) => {
|
|
90
|
+
const l = R(d), e = a == null ? void 0 : a.getBoundingClientRect();
|
|
91
|
+
e && (t.width = e.width, t.height = e.height), t.startTop = t.top, t.startRight = t.right, t.startX = l.x, t.startY = l.y, t.isDragging = !0;
|
|
92
|
+
}, u = () => {
|
|
93
|
+
t.isDragging = !1;
|
|
94
|
+
};
|
|
95
|
+
return window.addEventListener("mousemove", i), window.addEventListener("mouseup", u), window.addEventListener("touchmove", i), window.addEventListener("touchend", u), L(() => {
|
|
96
|
+
window.removeEventListener("mousemove", i), window.removeEventListener("mouseup", u), window.removeEventListener("touchmove", i), window.removeEventListener("touchend", u);
|
|
97
|
+
}), {
|
|
98
|
+
position: g,
|
|
99
|
+
startDrag: p
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
function nt(s) {
|
|
103
|
+
const {
|
|
104
|
+
titleToKeyMap: o,
|
|
105
|
+
headerSelector: r = ".k-schema-header",
|
|
106
|
+
rootMargin: c = "-20% 0px -60% 0px",
|
|
107
|
+
threshold: t = 0
|
|
108
|
+
} = s, g = T("");
|
|
109
|
+
let i = null;
|
|
110
|
+
const p = /* @__PURE__ */ new Map(), u = () => {
|
|
111
|
+
i == null || i.disconnect(), p.clear(), i = new IntersectionObserver(
|
|
112
|
+
(l) => {
|
|
113
|
+
for (const e of l) {
|
|
114
|
+
if (!e.isIntersecting)
|
|
115
|
+
continue;
|
|
116
|
+
const n = p.get(e.target);
|
|
117
|
+
n && (g.value = n);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
root: null,
|
|
122
|
+
rootMargin: c,
|
|
123
|
+
threshold: t
|
|
124
|
+
}
|
|
125
|
+
), document.querySelectorAll(r).forEach((l) => {
|
|
126
|
+
const e = l.textContent || "";
|
|
127
|
+
for (const [n, h] of Object.entries(o))
|
|
128
|
+
if (e.includes(n)) {
|
|
129
|
+
i == null || i.observe(l), p.set(l, h);
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}, d = () => {
|
|
134
|
+
setTimeout(u, 500);
|
|
135
|
+
};
|
|
136
|
+
return B(d), L(() => {
|
|
137
|
+
i == null || i.disconnect();
|
|
138
|
+
}), {
|
|
139
|
+
activeSection: g,
|
|
140
|
+
refresh: d
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
const st = /* @__PURE__ */ b({
|
|
144
|
+
__name: "SharedNav",
|
|
145
|
+
props: {
|
|
146
|
+
sections: {},
|
|
147
|
+
headerSelector: { default: ".k-schema-header" },
|
|
148
|
+
boundarySelector: { default: ".plugin-view" },
|
|
149
|
+
initialTop: { default: 100 },
|
|
150
|
+
initialRight: { default: 20 },
|
|
151
|
+
rootMargin: { default: "-20% 0px -60% 0px" },
|
|
152
|
+
threshold: { default: 0 }
|
|
153
|
+
},
|
|
154
|
+
setup(s) {
|
|
155
|
+
const o = s, r = T(!1), c = T(null), t = f(
|
|
156
|
+
() => o.sections.reduce(
|
|
157
|
+
(e, n) => (e[n.matchText ?? n.title] = n.key, e),
|
|
158
|
+
{}
|
|
159
|
+
)
|
|
160
|
+
), g = f(
|
|
161
|
+
() => o.sections.reduce(
|
|
162
|
+
(e, n) => (e[n.key] = n.matchText ?? n.title, e),
|
|
163
|
+
{}
|
|
164
|
+
)
|
|
165
|
+
), i = (e) => {
|
|
166
|
+
e.stopPropagation(), r.value = !r.value;
|
|
167
|
+
}, { position: p, startDrag: u } = ot({
|
|
168
|
+
initialTop: o.initialTop,
|
|
169
|
+
initialRight: o.initialRight,
|
|
170
|
+
boundarySelector: o.boundarySelector
|
|
171
|
+
}), d = (e) => {
|
|
172
|
+
u(e, c.value);
|
|
173
|
+
}, { activeSection: a } = nt({
|
|
174
|
+
titleToKeyMap: t.value,
|
|
175
|
+
headerSelector: o.headerSelector,
|
|
176
|
+
rootMargin: o.rootMargin,
|
|
177
|
+
threshold: o.threshold
|
|
178
|
+
}), l = (e) => {
|
|
179
|
+
a.value = e.key;
|
|
180
|
+
const n = document.querySelectorAll(o.headerSelector);
|
|
181
|
+
for (let h = 0; h < n.length; h += 1) {
|
|
182
|
+
const v = n[h];
|
|
183
|
+
if ((v.textContent || "").includes(g.value[e.key])) {
|
|
184
|
+
v.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
return (e, n) => (y(), _("div", {
|
|
190
|
+
ref_key: "containerRef",
|
|
191
|
+
ref: c,
|
|
192
|
+
class: m([e.$style.container, r.value ? e.$style.collapsed : ""]),
|
|
193
|
+
style: A(k(p))
|
|
194
|
+
}, [
|
|
195
|
+
w("div", {
|
|
196
|
+
class: m(e.$style.header),
|
|
197
|
+
onMousedown: d,
|
|
198
|
+
onTouchstart: d
|
|
199
|
+
}, [
|
|
200
|
+
x(P, {
|
|
201
|
+
class: m(e.$style.move)
|
|
202
|
+
}, null, 8, ["class"]),
|
|
203
|
+
w("div", {
|
|
204
|
+
class: m(e.$style.toggle),
|
|
205
|
+
onClick: i,
|
|
206
|
+
onMousedown: n[0] || (n[0] = D(() => {
|
|
207
|
+
}, ["stop"])),
|
|
208
|
+
onTouchstart: n[1] || (n[1] = D(() => {
|
|
209
|
+
}, ["stop"]))
|
|
210
|
+
}, [
|
|
211
|
+
x(F)
|
|
212
|
+
], 34)
|
|
213
|
+
], 34),
|
|
214
|
+
w("div", {
|
|
215
|
+
class: m(e.$style.body)
|
|
216
|
+
}, [
|
|
217
|
+
x(et, {
|
|
218
|
+
sections: s.sections,
|
|
219
|
+
"active-key": k(a),
|
|
220
|
+
onSelect: l
|
|
221
|
+
}, null, 8, ["sections", "active-key"])
|
|
222
|
+
], 2)
|
|
223
|
+
], 6));
|
|
224
|
+
}
|
|
225
|
+
}), it = "_container_pbgsl_2", ct = "_header_pbgsl_21", rt = "_move_pbgsl_36", lt = "_toggle_pbgsl_45", at = "_body_pbgsl_56", dt = "_collapsed_pbgsl_67", ut = {
|
|
226
|
+
container: it,
|
|
227
|
+
header: ct,
|
|
228
|
+
move: rt,
|
|
229
|
+
toggle: lt,
|
|
230
|
+
body: at,
|
|
231
|
+
collapsed: dt
|
|
232
|
+
}, ht = {
|
|
233
|
+
$style: ut
|
|
234
|
+
}, gt = /* @__PURE__ */ M(st, [["__cssModules", ht]]), pt = [
|
|
235
|
+
{ title: "基础设置", key: "basic" },
|
|
236
|
+
{ title: "原生工具", key: "nativeTools" },
|
|
237
|
+
{ title: "XML 工具", key: "xmlTools" },
|
|
238
|
+
{ title: "其他变量", key: "variables" },
|
|
239
|
+
{ title: "其他设置", key: "other" }
|
|
240
|
+
], mt = [
|
|
241
|
+
"chatluna-toolbox",
|
|
242
|
+
"koishi-plugin-chatluna-toolbox"
|
|
243
|
+
], yt = /* @__PURE__ */ b({
|
|
244
|
+
__name: "ToolboxDetailsLoader",
|
|
245
|
+
setup(s) {
|
|
246
|
+
const o = K("plugin:name"), r = pt, c = f(() => {
|
|
247
|
+
const t = (o == null ? void 0 : o.value) || "";
|
|
248
|
+
return mt.includes(t);
|
|
249
|
+
});
|
|
250
|
+
return (t, g) => c.value ? (y(), X(k(gt), {
|
|
251
|
+
key: 0,
|
|
252
|
+
sections: k(r)
|
|
253
|
+
}, null, 8, ["sections"])) : O("", !0);
|
|
254
|
+
}
|
|
255
|
+
}), wt = (s) => {
|
|
256
|
+
s.slot({
|
|
257
|
+
type: "plugin-details",
|
|
258
|
+
component: yt,
|
|
259
|
+
order: -999
|
|
260
|
+
});
|
|
261
|
+
};
|
|
262
|
+
export {
|
|
263
|
+
wt as default
|
|
264
|
+
};
|
package/dist/style.css
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@charset "UTF-8";._item_1m2kp_1{padding:8px 16px;font-size:13px;color:var(--k-text-normal);cursor:pointer;transition:all .2s ease;white-space:nowrap;border-radius:9999px;margin:4px 0;background:transparent}._item_1m2kp_1:hover{background:#0000000f;color:var(--k-text-active)}._item_1m2kp_1._active_1m2kp_16{color:#fff;background:var(--k-color-primary);font-weight:500}._container_pbgsl_2{position:absolute;z-index:1000;width:140px;max-width:90vw;max-height:70vh;background:transparent;display:flex;flex-direction:column;font-family:Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,微软雅黑,Arial,sans-serif;-webkit-user-select:none;user-select:none;overflow:visible}@media(max-width:768px){._container_pbgsl_2{width:120px;max-height:50vh}}._container_pbgsl_2 ._header_pbgsl_21{padding:6px 10px;display:flex;justify-content:space-between;align-items:center;cursor:move;background:#ffffffd9;border-radius:20px;-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);margin-bottom:8px;box-shadow:0 2px 8px #00000014}._container_pbgsl_2 ._header_pbgsl_21:hover{background:#fffffff2}._container_pbgsl_2 ._header_pbgsl_21 ._move_pbgsl_36{color:var(--k-text-light);cursor:grab;transition:color .2s}._container_pbgsl_2 ._header_pbgsl_21 ._move_pbgsl_36:active{cursor:grabbing;color:var(--k-color-primary)}._container_pbgsl_2 ._header_pbgsl_21 ._toggle_pbgsl_45{cursor:pointer;color:var(--k-text-light);transition:transform .3s ease,color .2s;display:flex;align-items:center;padding:2px}._container_pbgsl_2 ._header_pbgsl_21 ._toggle_pbgsl_45:hover{color:var(--k-color-primary)}._container_pbgsl_2 ._body_pbgsl_56{overflow-y:auto;padding:4px 0;transition:max-height .3s ease,opacity .3s ease;opacity:1;scrollbar-width:none;-ms-overflow-style:none}._container_pbgsl_2 ._body_pbgsl_56::-webkit-scrollbar{display:none}._container_pbgsl_2._collapsed_pbgsl_67{max-height:40px!important}._container_pbgsl_2._collapsed_pbgsl_67 ._body_pbgsl_56{max-height:0;padding:0;opacity:0;overflow:hidden}._container_pbgsl_2._collapsed_pbgsl_67 ._toggle_pbgsl_45{transform:rotate(180deg)}
|
package/lib/index.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __commonJS = (cb, mod) => function __require() {
|
|
9
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
10
|
+
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name2 in all)
|
|
8
13
|
__defProp(target, name2, { get: all[name2], enumerable: true });
|
|
@@ -15,8 +20,376 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
20
|
}
|
|
16
21
|
return to;
|
|
17
22
|
};
|
|
23
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
24
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
25
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
26
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
27
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
28
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
29
|
+
mod
|
|
30
|
+
));
|
|
18
31
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
32
|
|
|
33
|
+
// ../../packages/shared-chatluna-xmltools/lib/index.js
|
|
34
|
+
var require_lib = __commonJS({
|
|
35
|
+
"../../packages/shared-chatluna-xmltools/lib/index.js"(exports2, module2) {
|
|
36
|
+
"use strict";
|
|
37
|
+
var __defProp2 = Object.defineProperty;
|
|
38
|
+
var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor;
|
|
39
|
+
var __getOwnPropNames2 = Object.getOwnPropertyNames;
|
|
40
|
+
var __hasOwnProp2 = Object.prototype.hasOwnProperty;
|
|
41
|
+
var __export2 = (target, all) => {
|
|
42
|
+
for (var name2 in all)
|
|
43
|
+
__defProp2(target, name2, { get: all[name2], enumerable: true });
|
|
44
|
+
};
|
|
45
|
+
var __copyProps2 = (to, from, except, desc) => {
|
|
46
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
47
|
+
for (let key of __getOwnPropNames2(from))
|
|
48
|
+
if (!__hasOwnProp2.call(to, key) && key !== except)
|
|
49
|
+
__defProp2(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc2(from, key)) || desc.enumerable });
|
|
50
|
+
}
|
|
51
|
+
return to;
|
|
52
|
+
};
|
|
53
|
+
var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod);
|
|
54
|
+
var index_exports2 = {};
|
|
55
|
+
__export2(index_exports2, {
|
|
56
|
+
createCharacterTempRuntime: () => createCharacterTempRuntime2,
|
|
57
|
+
extractAssistantText: () => extractAssistantText,
|
|
58
|
+
extractTextContent: () => extractTextContent,
|
|
59
|
+
getMessageType: () => getMessageType,
|
|
60
|
+
isAssistantMessage: () => isAssistantMessage,
|
|
61
|
+
parseSelfClosingXmlTags: () => parseSelfClosingXmlTags2,
|
|
62
|
+
registerGetTempListener: () => registerGetTempListener,
|
|
63
|
+
subscribeAssistantResponses: () => subscribeAssistantResponses
|
|
64
|
+
});
|
|
65
|
+
module2.exports = __toCommonJS2(index_exports2);
|
|
66
|
+
function parseSelfClosingXmlTags2(text, tagName) {
|
|
67
|
+
const tags = Array.from(
|
|
68
|
+
text.matchAll(new RegExp(`<${tagName}\\b([^>]*)\\/>`, "gi"))
|
|
69
|
+
);
|
|
70
|
+
if (!tags.length) return [];
|
|
71
|
+
return tags.map((tag) => {
|
|
72
|
+
const attrText = String(tag[1] || "");
|
|
73
|
+
const attrs = {};
|
|
74
|
+
for (const pair of attrText.matchAll(/([a-zA-Z_][\w-]*)="([^"]*)"/g)) {
|
|
75
|
+
attrs[pair[1]] = pair[2];
|
|
76
|
+
}
|
|
77
|
+
return attrs;
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function getMessageType(message) {
|
|
81
|
+
if (!message) return "";
|
|
82
|
+
if (typeof message._getType === "function") {
|
|
83
|
+
return String(message._getType() || "").trim().toLowerCase();
|
|
84
|
+
}
|
|
85
|
+
return String(message.type || message.role || "").trim().toLowerCase();
|
|
86
|
+
}
|
|
87
|
+
function isAssistantMessage(message) {
|
|
88
|
+
const type = getMessageType(message);
|
|
89
|
+
return type === "assistant" || type === "ai";
|
|
90
|
+
}
|
|
91
|
+
function extractTextContent(value) {
|
|
92
|
+
if (typeof value === "string") return value;
|
|
93
|
+
if (value == null) return "";
|
|
94
|
+
if (Array.isArray(value)) {
|
|
95
|
+
return value.map((item) => extractTextContent(item)).join("");
|
|
96
|
+
}
|
|
97
|
+
if (typeof value !== "object") return "";
|
|
98
|
+
const record = value;
|
|
99
|
+
if (typeof record.text === "string") return record.text;
|
|
100
|
+
if (record.content !== void 0 && record.content !== value) {
|
|
101
|
+
return extractTextContent(record.content);
|
|
102
|
+
}
|
|
103
|
+
if (Array.isArray(record.children)) {
|
|
104
|
+
return extractTextContent(record.children);
|
|
105
|
+
}
|
|
106
|
+
if (typeof record.attrs === "object" && record.attrs) {
|
|
107
|
+
const attrs = record.attrs;
|
|
108
|
+
if (typeof attrs.content === "string") return attrs.content;
|
|
109
|
+
if (typeof attrs.text === "string") return attrs.text;
|
|
110
|
+
}
|
|
111
|
+
return "";
|
|
112
|
+
}
|
|
113
|
+
function extractAssistantText(message) {
|
|
114
|
+
if (!isAssistantMessage(message)) return "";
|
|
115
|
+
return extractTextContent(message?.content ?? message?.text).trim();
|
|
116
|
+
}
|
|
117
|
+
var GET_TEMP_TAG_PREFIX = "chatlunaXmlToolsGetTempTag";
|
|
118
|
+
var GET_TEMP_ORIGINAL_PREFIX = "chatlunaXmlToolsGetTempOriginal";
|
|
119
|
+
var GET_TEMP_LISTENERS_PREFIX = "chatlunaXmlToolsGetTempListeners";
|
|
120
|
+
function resolveSymbolNamespace(namespace) {
|
|
121
|
+
return namespace?.trim() || "default";
|
|
122
|
+
}
|
|
123
|
+
function resolveGetTempTag(namespace) {
|
|
124
|
+
return /* @__PURE__ */ Symbol.for(`${GET_TEMP_TAG_PREFIX}:${resolveSymbolNamespace(namespace)}`);
|
|
125
|
+
}
|
|
126
|
+
function resolveGetTempOriginal(namespace) {
|
|
127
|
+
return /* @__PURE__ */ Symbol.for(
|
|
128
|
+
`${GET_TEMP_ORIGINAL_PREFIX}:${resolveSymbolNamespace(namespace)}`
|
|
129
|
+
);
|
|
130
|
+
}
|
|
131
|
+
function resolveGetTempListeners(namespace) {
|
|
132
|
+
return /* @__PURE__ */ Symbol.for(
|
|
133
|
+
`${GET_TEMP_LISTENERS_PREFIX}:${resolveSymbolNamespace(namespace)}`
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
function registerGetTempListener(service, listener, options = {}) {
|
|
137
|
+
const getTemp = service.getTemp;
|
|
138
|
+
if (typeof getTemp !== "function") return null;
|
|
139
|
+
const tagKey = resolveGetTempTag(options.symbolNamespace);
|
|
140
|
+
const originalKey = resolveGetTempOriginal(options.symbolNamespace);
|
|
141
|
+
const listenersKey = resolveGetTempListeners(options.symbolNamespace);
|
|
142
|
+
const serviceRecord = service;
|
|
143
|
+
let listeners = serviceRecord[listenersKey];
|
|
144
|
+
if (!listeners) {
|
|
145
|
+
listeners = /* @__PURE__ */ new Set();
|
|
146
|
+
serviceRecord[listenersKey] = listeners;
|
|
147
|
+
}
|
|
148
|
+
if (!serviceRecord[tagKey]) {
|
|
149
|
+
Object.defineProperty(serviceRecord, originalKey, {
|
|
150
|
+
value: getTemp,
|
|
151
|
+
configurable: true,
|
|
152
|
+
enumerable: false,
|
|
153
|
+
writable: true
|
|
154
|
+
});
|
|
155
|
+
service.getTemp = async (...args) => {
|
|
156
|
+
const originalGetTemp = serviceRecord[originalKey];
|
|
157
|
+
const temp = await originalGetTemp?.apply(service, args);
|
|
158
|
+
const activeListeners = serviceRecord[listenersKey];
|
|
159
|
+
const session = options.resolveSession ? options.resolveSession(args) : args[0] && typeof args[0] === "object" ? args[0] : null;
|
|
160
|
+
if (temp && activeListeners?.size) {
|
|
161
|
+
for (const handler of Array.from(activeListeners)) {
|
|
162
|
+
handler(temp, session);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return temp;
|
|
166
|
+
};
|
|
167
|
+
serviceRecord[tagKey] = true;
|
|
168
|
+
}
|
|
169
|
+
listeners.add(listener);
|
|
170
|
+
return () => {
|
|
171
|
+
const currentListeners = serviceRecord[listenersKey];
|
|
172
|
+
currentListeners?.delete(listener);
|
|
173
|
+
if (currentListeners?.size) return;
|
|
174
|
+
const originalGetTemp = serviceRecord[originalKey];
|
|
175
|
+
if (originalGetTemp && service.getTemp !== originalGetTemp) {
|
|
176
|
+
service.getTemp = originalGetTemp;
|
|
177
|
+
}
|
|
178
|
+
delete serviceRecord[originalKey];
|
|
179
|
+
delete serviceRecord[tagKey];
|
|
180
|
+
delete serviceRecord[listenersKey];
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
var PUSH_DISPATCHER_PREFIX = "chatlunaXmlToolsPushDispatcher";
|
|
184
|
+
function resolvePushDispatcherKey(namespace) {
|
|
185
|
+
const target = namespace?.trim() || "default";
|
|
186
|
+
return /* @__PURE__ */ Symbol.for(`${PUSH_DISPATCHER_PREFIX}:${target}`);
|
|
187
|
+
}
|
|
188
|
+
function getDispatcher(messages, key) {
|
|
189
|
+
return messages[key] ?? null;
|
|
190
|
+
}
|
|
191
|
+
function setDispatcher(messages, key, dispatcher) {
|
|
192
|
+
const record = messages;
|
|
193
|
+
if (!dispatcher) {
|
|
194
|
+
delete record[key];
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
Object.defineProperty(record, key, {
|
|
198
|
+
value: dispatcher,
|
|
199
|
+
configurable: true,
|
|
200
|
+
enumerable: false,
|
|
201
|
+
writable: true
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
function restoreDispatcher(key, dispatcher) {
|
|
205
|
+
if (dispatcher.messages.push === dispatcher.patchedPush) {
|
|
206
|
+
dispatcher.messages.push = dispatcher.originalPush;
|
|
207
|
+
}
|
|
208
|
+
setDispatcher(dispatcher.messages, key, null);
|
|
209
|
+
}
|
|
210
|
+
function subscribeAssistantResponses(messages, options) {
|
|
211
|
+
const key = resolvePushDispatcherKey(options.symbolNamespace);
|
|
212
|
+
let dispatcher = getDispatcher(messages, key);
|
|
213
|
+
if (!dispatcher) {
|
|
214
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
215
|
+
const processedMessages = /* @__PURE__ */ new WeakSet();
|
|
216
|
+
const originalPush = messages.push;
|
|
217
|
+
const patchedPush = function patchedPush2(...items) {
|
|
218
|
+
const result = originalPush.apply(this, items);
|
|
219
|
+
for (const item of items) {
|
|
220
|
+
if (!item || typeof item !== "object") continue;
|
|
221
|
+
if (processedMessages.has(item)) continue;
|
|
222
|
+
processedMessages.add(item);
|
|
223
|
+
const message = item;
|
|
224
|
+
const response = extractAssistantText(message);
|
|
225
|
+
if (!response) continue;
|
|
226
|
+
for (const listener2 of Array.from(listeners)) {
|
|
227
|
+
try {
|
|
228
|
+
listener2(message);
|
|
229
|
+
} catch (error) {
|
|
230
|
+
options.onListenerError?.(error);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return result;
|
|
235
|
+
};
|
|
236
|
+
dispatcher = {
|
|
237
|
+
messages,
|
|
238
|
+
originalPush,
|
|
239
|
+
patchedPush,
|
|
240
|
+
listeners,
|
|
241
|
+
processedMessages
|
|
242
|
+
};
|
|
243
|
+
messages.push = patchedPush;
|
|
244
|
+
setDispatcher(messages, key, dispatcher);
|
|
245
|
+
}
|
|
246
|
+
const listener = (message) => {
|
|
247
|
+
const response = extractAssistantText(message);
|
|
248
|
+
if (!response) return;
|
|
249
|
+
options.onResponse({
|
|
250
|
+
response,
|
|
251
|
+
message,
|
|
252
|
+
session: options.getSession?.() ?? null
|
|
253
|
+
});
|
|
254
|
+
};
|
|
255
|
+
dispatcher.listeners.add(listener);
|
|
256
|
+
return () => {
|
|
257
|
+
const current = getDispatcher(messages, key);
|
|
258
|
+
if (!current) return;
|
|
259
|
+
current.listeners.delete(listener);
|
|
260
|
+
if (current.listeners.size > 0) return;
|
|
261
|
+
restoreDispatcher(key, current);
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
function createCharacterTempRuntime2(options) {
|
|
265
|
+
const {
|
|
266
|
+
getCharacterService,
|
|
267
|
+
symbolNamespace,
|
|
268
|
+
onResponse,
|
|
269
|
+
getMessages = (temp) => temp?.completionMessages,
|
|
270
|
+
resolveSession,
|
|
271
|
+
onServiceMissing,
|
|
272
|
+
onServiceChanged,
|
|
273
|
+
onBound,
|
|
274
|
+
onStarted,
|
|
275
|
+
onResponseError,
|
|
276
|
+
onListenerError
|
|
277
|
+
} = options;
|
|
278
|
+
const messageSubscriptions = /* @__PURE__ */ new WeakMap();
|
|
279
|
+
const sessionByMessages = /* @__PURE__ */ new WeakMap();
|
|
280
|
+
const trackedMessages = /* @__PURE__ */ new Set();
|
|
281
|
+
let detachGetTempListener = null;
|
|
282
|
+
let activeService = null;
|
|
283
|
+
let active = false;
|
|
284
|
+
const cleanupMessageSubscriptions = () => {
|
|
285
|
+
for (const messages of Array.from(trackedMessages)) {
|
|
286
|
+
messageSubscriptions.get(messages)?.();
|
|
287
|
+
messageSubscriptions.delete(messages);
|
|
288
|
+
sessionByMessages.delete(messages);
|
|
289
|
+
trackedMessages.delete(messages);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
const cleanupServiceBinding = () => {
|
|
293
|
+
detachGetTempListener?.();
|
|
294
|
+
detachGetTempListener = null;
|
|
295
|
+
activeService = null;
|
|
296
|
+
active = false;
|
|
297
|
+
};
|
|
298
|
+
const handleTemp = (temp, session) => {
|
|
299
|
+
const messages = getMessages(temp);
|
|
300
|
+
if (!Array.isArray(messages) || typeof messages.push !== "function") return;
|
|
301
|
+
sessionByMessages.set(messages, session);
|
|
302
|
+
if (messageSubscriptions.has(messages)) return;
|
|
303
|
+
const unsubscribe = subscribeAssistantResponses(messages, {
|
|
304
|
+
symbolNamespace,
|
|
305
|
+
getSession: () => sessionByMessages.get(messages) ?? null,
|
|
306
|
+
onListenerError,
|
|
307
|
+
onResponse: ({ response, message, session: boundSession }) => {
|
|
308
|
+
const text = response || extractAssistantText(message);
|
|
309
|
+
if (!text) return;
|
|
310
|
+
void Promise.resolve(
|
|
311
|
+
onResponse({
|
|
312
|
+
response: text,
|
|
313
|
+
message,
|
|
314
|
+
session: boundSession
|
|
315
|
+
})
|
|
316
|
+
).catch((error) => {
|
|
317
|
+
onResponseError?.(error);
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
trackedMessages.add(messages);
|
|
322
|
+
messageSubscriptions.set(messages, () => {
|
|
323
|
+
unsubscribe();
|
|
324
|
+
trackedMessages.delete(messages);
|
|
325
|
+
sessionByMessages.delete(messages);
|
|
326
|
+
});
|
|
327
|
+
};
|
|
328
|
+
const bindCurrentService = () => {
|
|
329
|
+
const service = getCharacterService();
|
|
330
|
+
if (!service || typeof service.getTemp !== "function") {
|
|
331
|
+
cleanupServiceBinding();
|
|
332
|
+
cleanupMessageSubscriptions();
|
|
333
|
+
onServiceMissing?.();
|
|
334
|
+
return { bound: false, changed: false, missing: true };
|
|
335
|
+
}
|
|
336
|
+
if (detachGetTempListener && activeService === service) {
|
|
337
|
+
active = true;
|
|
338
|
+
onServiceChanged?.({
|
|
339
|
+
changed: false,
|
|
340
|
+
previousService: activeService,
|
|
341
|
+
nextService: service
|
|
342
|
+
});
|
|
343
|
+
return { bound: true, changed: false, missing: false };
|
|
344
|
+
}
|
|
345
|
+
const previousService = activeService;
|
|
346
|
+
cleanupServiceBinding();
|
|
347
|
+
cleanupMessageSubscriptions();
|
|
348
|
+
const detach = registerGetTempListener(service, handleTemp, {
|
|
349
|
+
symbolNamespace,
|
|
350
|
+
resolveSession
|
|
351
|
+
});
|
|
352
|
+
if (!detach) {
|
|
353
|
+
onServiceMissing?.();
|
|
354
|
+
return { bound: false, changed: false, missing: true };
|
|
355
|
+
}
|
|
356
|
+
detachGetTempListener = detach;
|
|
357
|
+
activeService = service;
|
|
358
|
+
active = true;
|
|
359
|
+
onServiceChanged?.({
|
|
360
|
+
changed: previousService !== service,
|
|
361
|
+
previousService,
|
|
362
|
+
nextService: service
|
|
363
|
+
});
|
|
364
|
+
onBound?.({ service });
|
|
365
|
+
return {
|
|
366
|
+
bound: true,
|
|
367
|
+
changed: previousService !== service,
|
|
368
|
+
missing: false
|
|
369
|
+
};
|
|
370
|
+
};
|
|
371
|
+
return {
|
|
372
|
+
start: () => {
|
|
373
|
+
const { bound, changed, missing } = bindCurrentService();
|
|
374
|
+
if (!bound) {
|
|
375
|
+
if (!missing) {
|
|
376
|
+
onServiceMissing?.();
|
|
377
|
+
}
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
onStarted?.({ changed });
|
|
381
|
+
return true;
|
|
382
|
+
},
|
|
383
|
+
stop: () => {
|
|
384
|
+
cleanupServiceBinding();
|
|
385
|
+
cleanupMessageSubscriptions();
|
|
386
|
+
},
|
|
387
|
+
isActive: () => active
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
|
|
20
393
|
// src/index.ts
|
|
21
394
|
var index_exports = {};
|
|
22
395
|
__export(index_exports, {
|
|
@@ -50,7 +423,7 @@ __export(index_exports, {
|
|
|
50
423
|
hasReplyToolsEnabled: () => hasReplyToolsEnabled,
|
|
51
424
|
inject: () => inject,
|
|
52
425
|
name: () => name,
|
|
53
|
-
parseSelfClosingXmlTags: () => parseSelfClosingXmlTags,
|
|
426
|
+
parseSelfClosingXmlTags: () => import_shared_chatluna_xmltools.parseSelfClosingXmlTags,
|
|
54
427
|
registerCharacterReplyTools: () => registerCharacterReplyTools,
|
|
55
428
|
registerNativeTools: () => registerNativeTools,
|
|
56
429
|
registerVariables: () => registerVariables,
|
|
@@ -82,7 +455,7 @@ var import_koishi2 = require("koishi");
|
|
|
82
455
|
var DEFAULT_POKE_TOOL_DESCRIPTION = "\u5BF9\u6307\u5B9A\u7528\u6237\u6267\u884C\u6233\u4E00\u6233\u3002";
|
|
83
456
|
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";
|
|
84
457
|
var DEFAULT_SET_GROUP_CARD_TOOL_DESCRIPTION = "\u4FEE\u6539\u7FA4\u6210\u5458\u7684\u7FA4\u6635\u79F0\u3002";
|
|
85
|
-
var DEFAULT_SET_GROUP_BAN_TOOL_DESCRIPTION = "\
|
|
458
|
+
var DEFAULT_SET_GROUP_BAN_TOOL_DESCRIPTION = "\u7528\u4E8E\u7BA1\u7406\u7FA4\u6210\u5458\u7981\u8A00\u72B6\u6001\uFF0C\u53EF\u8BBE\u7F6E\u7981\u8A00\u65F6\u957F\u6216\u89E3\u9664\u7981\u8A00\u3002";
|
|
86
459
|
var DEFAULT_SET_MSG_EMOJI_TOOL_DESCRIPTION = "\u5BF9\u6307\u5B9A\u6D88\u606F\u6DFB\u52A0\u8868\u60C5\u56DE\u5E94\u3002";
|
|
87
460
|
var DEFAULT_DELETE_MESSAGE_TOOL_DESCRIPTION = "\u6839\u636E\u6D88\u606F ID \u64A4\u56DE\u6307\u5B9A\u6D88\u606F\u3002";
|
|
88
461
|
|
|
@@ -210,7 +583,7 @@ var XmlToolsSchema = import_koishi3.Schema.object({
|
|
|
210
583
|
enableBanXmlTool: import_koishi3.Schema.boolean().default(false).description(
|
|
211
584
|
"\u542F\u7528 XML \u5F62\u5F0F\u7684\u7FA4\u6210\u5458\u7981\u8A00\u8C03\u7528\uFF08\u4E0E \u539F\u751F\u5DE5\u5177 \u4E8C\u9009\u4E00\uFF09"
|
|
212
585
|
),
|
|
213
|
-
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")
|
|
586
|
+
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\uFF1B\u82E5\u5F00\u542F\u201C\u5C06 XML \u5DE5\u5177\u6539\u4E3A\u6CE8\u5165\u5B9E\u9A8C\u6027\u5DE5\u5177\u8C03\u7528\u56DE\u590D\u201D\uFF0C\u5219\u65E0\u9700\u589E\u52A0\u989D\u5916\u63D0\u793A\u8BCD")
|
|
214
587
|
}).description("XML \u5DE5\u5177");
|
|
215
588
|
|
|
216
589
|
// src/schema/variables.ts
|
|
@@ -326,6 +699,9 @@ var ConfigSchema = import_koishi5.Schema.intersect([
|
|
|
326
699
|
OtherSettingsSchema
|
|
327
700
|
]);
|
|
328
701
|
|
|
702
|
+
// src/plugin.ts
|
|
703
|
+
var path = __toESM(require("path"));
|
|
704
|
+
|
|
329
705
|
// src/helpers/logger.ts
|
|
330
706
|
function createLogger(ctx, config) {
|
|
331
707
|
const logger = ctx.logger("chatluna-toolbox");
|
|
@@ -725,6 +1101,20 @@ function createSetProfileTool(deps) {
|
|
|
725
1101
|
}
|
|
726
1102
|
|
|
727
1103
|
// src/features/native-tools/register.ts
|
|
1104
|
+
var NATIVE_TOOL_DEFAULT_AVAILABILITY = {
|
|
1105
|
+
enabled: true,
|
|
1106
|
+
main: true,
|
|
1107
|
+
chatluna: true,
|
|
1108
|
+
characterScope: "all"
|
|
1109
|
+
};
|
|
1110
|
+
function createNativeToolMeta(group, tags) {
|
|
1111
|
+
return {
|
|
1112
|
+
source: "extension",
|
|
1113
|
+
group,
|
|
1114
|
+
tags,
|
|
1115
|
+
defaultAvailability: NATIVE_TOOL_DEFAULT_AVAILABILITY
|
|
1116
|
+
};
|
|
1117
|
+
}
|
|
728
1118
|
function resolveToolName(value, fallback) {
|
|
729
1119
|
const trimmedValue = value.trim();
|
|
730
1120
|
return trimmedValue || fallback;
|
|
@@ -754,7 +1144,9 @@ function registerNativeTools(deps) {
|
|
|
754
1144
|
plugin.registerTool(toolName, {
|
|
755
1145
|
selector: () => true,
|
|
756
1146
|
authorization: (session) => session?.platform === "onebot",
|
|
757
|
-
|
|
1147
|
+
description,
|
|
1148
|
+
createTool: () => createPokeTool({ ctx, toolName, description, log, protocol }),
|
|
1149
|
+
meta: createNativeToolMeta("onebot", ["poke"])
|
|
758
1150
|
});
|
|
759
1151
|
log?.("info", `\u6233\u4E00\u6233\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
|
|
760
1152
|
}
|
|
@@ -770,7 +1162,9 @@ function registerNativeTools(deps) {
|
|
|
770
1162
|
plugin.registerTool(toolName, {
|
|
771
1163
|
selector: () => true,
|
|
772
1164
|
authorization: (session) => session?.platform === "onebot",
|
|
773
|
-
|
|
1165
|
+
description,
|
|
1166
|
+
createTool: () => createSetProfileTool({ ctx, toolName, description, log, protocol }),
|
|
1167
|
+
meta: createNativeToolMeta("onebot", [])
|
|
774
1168
|
});
|
|
775
1169
|
log?.("info", `\u8BBE\u7F6E\u8D44\u6599\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
|
|
776
1170
|
}
|
|
@@ -786,7 +1180,9 @@ function registerNativeTools(deps) {
|
|
|
786
1180
|
plugin.registerTool(toolName, {
|
|
787
1181
|
selector: () => true,
|
|
788
1182
|
authorization: (session) => session?.platform === "onebot",
|
|
789
|
-
|
|
1183
|
+
description,
|
|
1184
|
+
createTool: () => createSetGroupCardTool({ ctx, toolName, description, log }),
|
|
1185
|
+
meta: createNativeToolMeta("onebot", ["group"])
|
|
790
1186
|
});
|
|
791
1187
|
log?.("info", `\u7FA4\u6635\u79F0\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
|
|
792
1188
|
}
|
|
@@ -802,7 +1198,9 @@ function registerNativeTools(deps) {
|
|
|
802
1198
|
plugin.registerTool(toolName, {
|
|
803
1199
|
selector: () => true,
|
|
804
1200
|
authorization: (session) => session?.platform === "onebot",
|
|
805
|
-
|
|
1201
|
+
description,
|
|
1202
|
+
createTool: () => createSetGroupBanTool({ toolName, description, log, protocol }),
|
|
1203
|
+
meta: createNativeToolMeta("onebot", ["group"])
|
|
806
1204
|
});
|
|
807
1205
|
log?.("info", `\u7FA4\u6210\u5458\u7981\u8A00\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
|
|
808
1206
|
}
|
|
@@ -818,7 +1216,9 @@ function registerNativeTools(deps) {
|
|
|
818
1216
|
plugin.registerTool(toolName, {
|
|
819
1217
|
selector: () => true,
|
|
820
1218
|
authorization: (session) => session?.platform === "onebot",
|
|
821
|
-
|
|
1219
|
+
description,
|
|
1220
|
+
createTool: () => createSetMsgEmojiTool({ toolName, description, log, protocol }),
|
|
1221
|
+
meta: createNativeToolMeta("onebot", ["message"])
|
|
822
1222
|
});
|
|
823
1223
|
log?.("info", `\u6D88\u606F\u8868\u60C5\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
|
|
824
1224
|
}
|
|
@@ -834,7 +1234,9 @@ function registerNativeTools(deps) {
|
|
|
834
1234
|
plugin.registerTool(toolName, {
|
|
835
1235
|
selector: () => true,
|
|
836
1236
|
authorization: (session) => session?.platform === "onebot",
|
|
837
|
-
|
|
1237
|
+
description,
|
|
1238
|
+
createTool: () => createDeleteMessageTool({ toolName, description, log }),
|
|
1239
|
+
meta: createNativeToolMeta("onebot", ["message"])
|
|
838
1240
|
});
|
|
839
1241
|
log?.("info", `\u5220\u9664\u6D88\u606F\u5DE5\u5177\u5DF2\u6CE8\u518C: ${toolName}`);
|
|
840
1242
|
}
|
|
@@ -1088,20 +1490,7 @@ function registerCharacterReplyTools(deps) {
|
|
|
1088
1490
|
}
|
|
1089
1491
|
|
|
1090
1492
|
// src/features/xml-tools/parser.ts
|
|
1091
|
-
|
|
1092
|
-
const tags = Array.from(
|
|
1093
|
-
text.matchAll(new RegExp(`<${tagName}\\b([^>]*)\\/>`, "gi"))
|
|
1094
|
-
);
|
|
1095
|
-
if (!tags.length) return [];
|
|
1096
|
-
return tags.map((tag) => {
|
|
1097
|
-
const attrText = String(tag[1] || "");
|
|
1098
|
-
const attrs = {};
|
|
1099
|
-
for (const pair of attrText.matchAll(/([a-zA-Z_][\w-]*)="([^"]*)"/g)) {
|
|
1100
|
-
attrs[pair[1]] = pair[2];
|
|
1101
|
-
}
|
|
1102
|
-
return attrs;
|
|
1103
|
-
});
|
|
1104
|
-
}
|
|
1493
|
+
var import_shared_chatluna_xmltools = __toESM(require_lib());
|
|
1105
1494
|
|
|
1106
1495
|
// src/features/xml-tools/processor.ts
|
|
1107
1496
|
function createXmlProcessor(deps) {
|
|
@@ -1120,10 +1509,10 @@ function createXmlProcessor(deps) {
|
|
|
1120
1509
|
}) => {
|
|
1121
1510
|
const content = String(response || "").trim();
|
|
1122
1511
|
if (!content) return false;
|
|
1123
|
-
const pokeTags = parseSelfClosingXmlTags(content, "poke");
|
|
1124
|
-
const emojiTags = parseSelfClosingXmlTags(content, "emoji");
|
|
1125
|
-
const deleteTags = parseSelfClosingXmlTags(content, "delete");
|
|
1126
|
-
const banTags = parseSelfClosingXmlTags(content, "ban");
|
|
1512
|
+
const pokeTags = (0, import_shared_chatluna_xmltools.parseSelfClosingXmlTags)(content, "poke");
|
|
1513
|
+
const emojiTags = (0, import_shared_chatluna_xmltools.parseSelfClosingXmlTags)(content, "emoji");
|
|
1514
|
+
const deleteTags = (0, import_shared_chatluna_xmltools.parseSelfClosingXmlTags)(content, "delete");
|
|
1515
|
+
const banTags = (0, import_shared_chatluna_xmltools.parseSelfClosingXmlTags)(content, "ban");
|
|
1127
1516
|
let handled = false;
|
|
1128
1517
|
if (config.enablePokeXmlTool && pokeTags.length > 0) {
|
|
1129
1518
|
if (!session) {
|
|
@@ -1208,208 +1597,23 @@ function createXmlProcessor(deps) {
|
|
|
1208
1597
|
}
|
|
1209
1598
|
|
|
1210
1599
|
// src/features/xml-tools/temp-runtime.ts
|
|
1211
|
-
var
|
|
1212
|
-
var GET_TEMP_ORIGINAL = /* @__PURE__ */ Symbol.for("chatlunaToolboxXmlOriginalGetTemp");
|
|
1213
|
-
var GET_TEMP_LISTENERS = /* @__PURE__ */ Symbol.for("chatlunaToolboxXmlGetTempListeners");
|
|
1214
|
-
var PUSH_DISPATCHER = /* @__PURE__ */ Symbol.for("chatlunaToolboxXmlPushDispatcher");
|
|
1215
|
-
function getMessageType(message) {
|
|
1216
|
-
if (!message) return "";
|
|
1217
|
-
if (typeof message._getType === "function") {
|
|
1218
|
-
return String(message._getType() || "").trim().toLowerCase();
|
|
1219
|
-
}
|
|
1220
|
-
return String(message.type || message.role || "").trim().toLowerCase();
|
|
1221
|
-
}
|
|
1222
|
-
function isAssistantMessage(message) {
|
|
1223
|
-
const type = getMessageType(message);
|
|
1224
|
-
return type === "ai" || type === "assistant";
|
|
1225
|
-
}
|
|
1226
|
-
function extractText(value) {
|
|
1227
|
-
if (typeof value === "string") return value;
|
|
1228
|
-
if (value == null) return "";
|
|
1229
|
-
if (Array.isArray(value)) {
|
|
1230
|
-
return value.map((item) => extractText(item)).join("");
|
|
1231
|
-
}
|
|
1232
|
-
if (typeof value !== "object") return "";
|
|
1233
|
-
const record = value;
|
|
1234
|
-
if (typeof record.text === "string") return record.text;
|
|
1235
|
-
if (record.content !== void 0 && record.content !== value) {
|
|
1236
|
-
return extractText(record.content);
|
|
1237
|
-
}
|
|
1238
|
-
if (Array.isArray(record.children)) return extractText(record.children);
|
|
1239
|
-
if (typeof record.attrs === "object" && record.attrs) {
|
|
1240
|
-
const attrs = record.attrs;
|
|
1241
|
-
if (typeof attrs.content === "string") return attrs.content;
|
|
1242
|
-
if (typeof attrs.text === "string") return attrs.text;
|
|
1243
|
-
}
|
|
1244
|
-
return "";
|
|
1245
|
-
}
|
|
1246
|
-
function getResponseText(message) {
|
|
1247
|
-
if (!isAssistantMessage(message)) return "";
|
|
1248
|
-
return extractText(message?.content ?? message?.text).trim();
|
|
1249
|
-
}
|
|
1250
|
-
function getDispatcher(messages) {
|
|
1251
|
-
return messages[PUSH_DISPATCHER] ?? null;
|
|
1252
|
-
}
|
|
1253
|
-
function setDispatcher(messages, dispatcher) {
|
|
1254
|
-
const record = messages;
|
|
1255
|
-
if (!dispatcher) {
|
|
1256
|
-
delete record[PUSH_DISPATCHER];
|
|
1257
|
-
return;
|
|
1258
|
-
}
|
|
1259
|
-
Object.defineProperty(record, PUSH_DISPATCHER, {
|
|
1260
|
-
value: dispatcher,
|
|
1261
|
-
configurable: true,
|
|
1262
|
-
enumerable: false,
|
|
1263
|
-
writable: true
|
|
1264
|
-
});
|
|
1265
|
-
}
|
|
1266
|
-
function attachDispatcher(messages, log) {
|
|
1267
|
-
const existing = getDispatcher(messages);
|
|
1268
|
-
if (existing) return existing;
|
|
1269
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
1270
|
-
const processedMessages = /* @__PURE__ */ new WeakSet();
|
|
1271
|
-
const originalPush = messages.push;
|
|
1272
|
-
const patchedPush = function patchedPush2(...items) {
|
|
1273
|
-
const result = originalPush.apply(this, items);
|
|
1274
|
-
for (const item of items) {
|
|
1275
|
-
if (!item || typeof item !== "object") continue;
|
|
1276
|
-
const message = item;
|
|
1277
|
-
if (!isAssistantMessage(message)) continue;
|
|
1278
|
-
if (processedMessages.has(item)) continue;
|
|
1279
|
-
const response = getResponseText(message);
|
|
1280
|
-
if (!response) continue;
|
|
1281
|
-
processedMessages.add(item);
|
|
1282
|
-
for (const listener of Array.from(listeners)) {
|
|
1283
|
-
try {
|
|
1284
|
-
listener(message);
|
|
1285
|
-
} catch (error) {
|
|
1286
|
-
log?.("warn", "\u5904\u7406 XML completionMessages \u76D1\u542C\u5668\u5931\u8D25", error);
|
|
1287
|
-
}
|
|
1288
|
-
}
|
|
1289
|
-
}
|
|
1290
|
-
return result;
|
|
1291
|
-
};
|
|
1292
|
-
const dispatcher = {
|
|
1293
|
-
messages,
|
|
1294
|
-
originalPush,
|
|
1295
|
-
patchedPush,
|
|
1296
|
-
listeners,
|
|
1297
|
-
processedMessages
|
|
1298
|
-
};
|
|
1299
|
-
messages.push = patchedPush;
|
|
1300
|
-
setDispatcher(messages, dispatcher);
|
|
1301
|
-
return dispatcher;
|
|
1302
|
-
}
|
|
1303
|
-
function restoreDispatcher(dispatcher) {
|
|
1304
|
-
if (dispatcher.messages.push === dispatcher.patchedPush) {
|
|
1305
|
-
dispatcher.messages.push = dispatcher.originalPush;
|
|
1306
|
-
}
|
|
1307
|
-
setDispatcher(dispatcher.messages, null);
|
|
1308
|
-
}
|
|
1309
|
-
function registerGetTempListener(service, listener) {
|
|
1310
|
-
const getTemp = service.getTemp;
|
|
1311
|
-
if (typeof getTemp !== "function") return null;
|
|
1312
|
-
const serviceRecord = service;
|
|
1313
|
-
let listeners = serviceRecord[GET_TEMP_LISTENERS];
|
|
1314
|
-
if (!listeners) {
|
|
1315
|
-
listeners = /* @__PURE__ */ new Set();
|
|
1316
|
-
serviceRecord[GET_TEMP_LISTENERS] = listeners;
|
|
1317
|
-
}
|
|
1318
|
-
if (!serviceRecord[GET_TEMP_TAG]) {
|
|
1319
|
-
Object.defineProperty(serviceRecord, GET_TEMP_ORIGINAL, {
|
|
1320
|
-
value: getTemp,
|
|
1321
|
-
configurable: true,
|
|
1322
|
-
enumerable: false,
|
|
1323
|
-
writable: true
|
|
1324
|
-
});
|
|
1325
|
-
service.getTemp = async (...args) => {
|
|
1326
|
-
const originalGetTemp = serviceRecord[GET_TEMP_ORIGINAL];
|
|
1327
|
-
const temp = await originalGetTemp?.apply(
|
|
1328
|
-
service,
|
|
1329
|
-
args
|
|
1330
|
-
);
|
|
1331
|
-
const activeListeners = serviceRecord[GET_TEMP_LISTENERS];
|
|
1332
|
-
const session = args[0] && typeof args[0] === "object" ? args[0] : null;
|
|
1333
|
-
if (temp && activeListeners?.size) {
|
|
1334
|
-
for (const handler of Array.from(activeListeners)) {
|
|
1335
|
-
handler(temp, session);
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
return temp;
|
|
1339
|
-
};
|
|
1340
|
-
serviceRecord[GET_TEMP_TAG] = true;
|
|
1341
|
-
}
|
|
1342
|
-
listeners.add(listener);
|
|
1343
|
-
return () => {
|
|
1344
|
-
const currentListeners = serviceRecord[GET_TEMP_LISTENERS];
|
|
1345
|
-
currentListeners?.delete(listener);
|
|
1346
|
-
if (currentListeners?.size) return;
|
|
1347
|
-
const originalGetTemp = serviceRecord[GET_TEMP_ORIGINAL];
|
|
1348
|
-
if (originalGetTemp) service.getTemp = originalGetTemp;
|
|
1349
|
-
delete serviceRecord[GET_TEMP_ORIGINAL];
|
|
1350
|
-
delete serviceRecord[GET_TEMP_TAG];
|
|
1351
|
-
delete serviceRecord[GET_TEMP_LISTENERS];
|
|
1352
|
-
};
|
|
1353
|
-
}
|
|
1600
|
+
var import_shared_chatluna_xmltools2 = __toESM(require_lib());
|
|
1354
1601
|
function createCharacterTempXmlRuntime(params) {
|
|
1355
1602
|
const { getCharacterService, processModelResponse, log } = params;
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
};
|
|
1363
|
-
const hasAttachedListener = (dispatcher) => {
|
|
1364
|
-
compactAttachedDispatchers();
|
|
1365
|
-
return attachedDispatchers.some(
|
|
1366
|
-
(entry) => entry.ref.deref() === dispatcher
|
|
1367
|
-
);
|
|
1368
|
-
};
|
|
1369
|
-
const detachDispatcherListener = (entry) => {
|
|
1370
|
-
const dispatcher = entry.ref.deref();
|
|
1371
|
-
if (!dispatcher) return;
|
|
1372
|
-
dispatcher.listeners.delete(entry.listener);
|
|
1373
|
-
if (dispatcher.listeners.size === 0) restoreDispatcher(dispatcher);
|
|
1374
|
-
};
|
|
1375
|
-
const handleTemp = (temp, session) => {
|
|
1376
|
-
const messages = temp.completionMessages;
|
|
1377
|
-
if (!Array.isArray(messages) || typeof messages.push !== "function") return;
|
|
1378
|
-
const dispatcher = attachDispatcher(messages, log);
|
|
1379
|
-
if (hasAttachedListener(dispatcher)) return;
|
|
1380
|
-
const listener = (message) => {
|
|
1381
|
-
const response = getResponseText(message);
|
|
1382
|
-
if (!response) return;
|
|
1383
|
-
void processModelResponse({ response, session }).catch((error) => {
|
|
1384
|
-
log?.("warn", "\u5904\u7406 XML \u6A21\u578B\u54CD\u5E94\u5931\u8D25", error);
|
|
1385
|
-
});
|
|
1386
|
-
};
|
|
1387
|
-
dispatcher.listeners.add(listener);
|
|
1388
|
-
attachedDispatchers.push({ ref: new WeakRef(dispatcher), listener });
|
|
1389
|
-
};
|
|
1390
|
-
return {
|
|
1391
|
-
start: () => {
|
|
1392
|
-
if (stopListening) return true;
|
|
1393
|
-
const service = getCharacterService();
|
|
1394
|
-
if (!service) return false;
|
|
1395
|
-
const detach = registerGetTempListener(service, handleTemp);
|
|
1396
|
-
if (!detach) return false;
|
|
1397
|
-
stopListening = () => {
|
|
1398
|
-
compactAttachedDispatchers();
|
|
1399
|
-
for (const entry of attachedDispatchers) {
|
|
1400
|
-
detachDispatcherListener(entry);
|
|
1401
|
-
}
|
|
1402
|
-
attachedDispatchers = [];
|
|
1403
|
-
detach();
|
|
1404
|
-
stopListening = null;
|
|
1405
|
-
};
|
|
1406
|
-
return true;
|
|
1603
|
+
return (0, import_shared_chatluna_xmltools2.createCharacterTempRuntime)({
|
|
1604
|
+
getCharacterService,
|
|
1605
|
+
symbolNamespace: "chatluna-toolbox",
|
|
1606
|
+
resolveSession: (args) => args[0] && typeof args[0] === "object" ? args[0] : null,
|
|
1607
|
+
onListenerError: (error) => {
|
|
1608
|
+
log?.("warn", "\u5904\u7406 XML completionMessages \u76D1\u542C\u5668\u5931\u8D25", error);
|
|
1407
1609
|
},
|
|
1408
|
-
|
|
1409
|
-
|
|
1610
|
+
onResponseError: (error) => {
|
|
1611
|
+
log?.("warn", "\u5904\u7406 XML \u6A21\u578B\u54CD\u5E94\u5931\u8D25", error);
|
|
1410
1612
|
},
|
|
1411
|
-
|
|
1412
|
-
|
|
1613
|
+
onResponse: async ({ response, session }) => {
|
|
1614
|
+
await processModelResponse({ response, session });
|
|
1615
|
+
}
|
|
1616
|
+
});
|
|
1413
1617
|
}
|
|
1414
1618
|
|
|
1415
1619
|
// src/features/xml-tools/register.ts
|
|
@@ -2139,6 +2343,13 @@ function registerVariables(deps) {
|
|
|
2139
2343
|
|
|
2140
2344
|
// src/plugin.ts
|
|
2141
2345
|
function apply(ctx, config) {
|
|
2346
|
+
ctx.inject(["console"], (innerCtx) => {
|
|
2347
|
+
const consoleService = innerCtx.console;
|
|
2348
|
+
consoleService?.addEntry?.({
|
|
2349
|
+
dev: path.resolve(__dirname, "../client/index.ts"),
|
|
2350
|
+
prod: path.resolve(__dirname, "../dist")
|
|
2351
|
+
});
|
|
2352
|
+
});
|
|
2142
2353
|
const chatlunaService = ctx.chatluna;
|
|
2143
2354
|
const plugin = {
|
|
2144
2355
|
registerTool: (name2, tool) => {
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-chatluna-toolbox",
|
|
3
3
|
"description": "为 ChatLuna 提供更多原生工具、XML 工具与变量,仅支持 onebot 平台。",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.12",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
8
|
-
"lib"
|
|
8
|
+
"lib",
|
|
9
|
+
"dist",
|
|
10
|
+
"client"
|
|
9
11
|
],
|
|
10
12
|
"license": "MIT",
|
|
11
13
|
"homepage": "https://github.com/Sor85/koishi-plugins",
|
|
@@ -22,11 +24,15 @@
|
|
|
22
24
|
"peerDependencies": {
|
|
23
25
|
"koishi": "^4.18.7",
|
|
24
26
|
"koishi-plugin-chatluna": "*",
|
|
25
|
-
"koishi-plugin-chatluna-character": "*"
|
|
27
|
+
"koishi-plugin-chatluna-character": "*",
|
|
28
|
+
"@koishijs/plugin-console": "^5.30.0"
|
|
26
29
|
},
|
|
27
30
|
"peerDependenciesMeta": {
|
|
28
31
|
"koishi-plugin-chatluna-character": {
|
|
29
32
|
"optional": true
|
|
33
|
+
},
|
|
34
|
+
"@koishijs/plugin-console": {
|
|
35
|
+
"optional": true
|
|
30
36
|
}
|
|
31
37
|
},
|
|
32
38
|
"dependencies": {
|
|
@@ -34,13 +40,19 @@
|
|
|
34
40
|
"zod": "^3.25.76"
|
|
35
41
|
},
|
|
36
42
|
"devDependencies": {
|
|
43
|
+
"@koishijs/client": "^5.30.0",
|
|
37
44
|
"@types/node": "^22.10.1",
|
|
45
|
+
"@vitejs/plugin-vue": "^6.0.2",
|
|
46
|
+
"sass": "^1.77.0",
|
|
38
47
|
"tsup": "^8.0.0",
|
|
39
48
|
"typescript": "^5.7.2",
|
|
40
|
-
"
|
|
49
|
+
"vite": "^6.0.0",
|
|
50
|
+
"vitest": "^3.2.4",
|
|
51
|
+
"shared-chatluna-xmltools": "0.0.1",
|
|
52
|
+
"shared-nav": "0.0.1"
|
|
41
53
|
},
|
|
42
54
|
"scripts": {
|
|
43
|
-
"build": "tsup",
|
|
55
|
+
"build": "tsup && vite build",
|
|
44
56
|
"watch": "tsup --watch",
|
|
45
57
|
"typecheck": "NODE_OPTIONS=--max-old-space-size=8192 tsc --noEmit",
|
|
46
58
|
"test": "vitest run"
|