dsh-qq-link 1.5.4 → 1.5.6
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/CHANGELOG.md +25 -0
- package/lib/host.js +42 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
## 1.5.6 — 2026-11-11
|
|
2
|
+
|
|
3
|
+
**回复门槛 / QQ 空间那五个工具:会话建出来就当场挂,不再等轮询那一跳**
|
|
4
|
+
|
|
5
|
+
- 🐞 这两批工具是「按会话挂」的(只有绑了 QQ 的那几间屋才有),以前只在收消息那一跳
|
|
6
|
+
(默认 2 秒一次)里顺带挂。重启之后第一句要是比那一跳快,那一轮的工具表就少几条 ——
|
|
7
|
+
前缀跟着变,**整段历史按未缓存重算一次**(实测 34.6 万 token)。
|
|
8
|
+
- 现在接 `agent/created` / `agent/disposed`:会话一建好就挂、销毁就摘,没有空档;
|
|
9
|
+
轮询那一跳照旧留着当兜底。
|
|
10
|
+
- 🐞 回复门槛以前只看「这个会话挂过没有」—— 会话重开、插件重载换了 agent 实例之后就不重挂,
|
|
11
|
+
那间屋的门槛工具从此永久没了。现在按「会话 + 实例」记,实例变了就重挂。
|
|
12
|
+
- 🐞 空间工具换实例时只挂新的、不摘旧的,会留两份。现在先摘再挂。
|
|
13
|
+
|
|
14
|
+
## 1.5.5 — 2026-11-10
|
|
15
|
+
|
|
16
|
+
**QQ 空间「看单条说说」会把整轮对话弄崩:tid 被声明成了整数**
|
|
17
|
+
|
|
18
|
+
- 🐞 `qq_space_detail` 的 `tid` 参数类型写的是 `integer`,可它其实是 24 位十六进制的一串字符。
|
|
19
|
+
模型照着「整数」去填就不加引号,写出来是个**非法 JSON**,整轮直接被判失败
|
|
20
|
+
(`DeepSeek Messages stream: tool input is invalid JSON`),重试几次都一样。
|
|
21
|
+
- 🐞 列表里输出 tid 时也没带引号,模型原样抄下来正好踩进这个坑。
|
|
22
|
+
- 🐞 执行时又拿 `Math.round(Number())` 去转:十六进制转出来是 NaN,长数字串还会丢精度。
|
|
23
|
+
- 现在:`tid` 声明成 `string`,列表输出带引号,执行时原样当字符串往下传
|
|
24
|
+
(模型还是给数字也照收,转成字符串再用)。
|
|
25
|
+
|
|
1
26
|
## 1.5.4 — 2026-11-07
|
|
2
27
|
|
|
3
28
|
**宿主 0.2.2 起,QQ 空间的四个工具每 2 秒报一次 already registered,日志被刷爆**
|
package/lib/host.js
CHANGED
|
@@ -2564,7 +2564,7 @@ export function apply(ctx) {
|
|
|
2564
2564
|
// 「工具调用 · Error: tool call aborted」+ 宿主开始「重试模型请求 (1/5)」,看着像坏了。
|
|
2565
2565
|
// 现在改成**不停轮、只把这轮的出站掐掉**:工具返回一句「这轮不接」,并在这一轮结束时跳过发送。
|
|
2566
2566
|
const 静默轮 = new Set() // 会话键
|
|
2567
|
-
const 闸门挂着 = new Map() // sid ->
|
|
2567
|
+
const 闸门挂着 = new Map() // sid -> { agent, off }
|
|
2568
2568
|
const QqWalake窗口 = 10 * 60 * 1000
|
|
2569
2569
|
|
|
2570
2570
|
// ── 群聊的节奏(1.0.9:**只要两个数**)──
|
|
@@ -2799,20 +2799,27 @@ export function apply(ctx) {
|
|
|
2799
2799
|
const agent = 找agent(id)
|
|
2800
2800
|
if (!agent) continue
|
|
2801
2801
|
const sid = 会话键((agent.session && agent.session.id) || id)
|
|
2802
|
-
|
|
2802
|
+
const 已 = 闸门挂着.get(sid)
|
|
2803
|
+
// ⭐ 1.5.6:按「sid + agent 实例」记。以前只看 sid 在不在,
|
|
2804
|
+
// 会话重开 / 插件重载换了实例就不重挂 —— 那间屋的门槛工具从此永久没了。
|
|
2805
|
+
if (已 && 已.agent === agent) continue
|
|
2806
|
+
if (已) {
|
|
2807
|
+
try { if (typeof 已.off === 'function') 已.off() } catch (error) {}
|
|
2808
|
+
闸门挂着.delete(sid)
|
|
2809
|
+
}
|
|
2803
2810
|
try {
|
|
2804
2811
|
const off = agent.ctx.tools.register(做闸门工具(agent, sid))
|
|
2805
|
-
闸门挂着.set(sid, off)
|
|
2812
|
+
闸门挂着.set(sid, { agent, off })
|
|
2806
2813
|
记账('回复门槛已挂上(' + 短id(sid) + ')')
|
|
2807
2814
|
} catch (error) {
|
|
2808
2815
|
记账('回复门槛挂不上(' + 短id(sid) + '):' + String((error && error.message) || error))
|
|
2809
2816
|
}
|
|
2810
2817
|
}
|
|
2811
2818
|
// 卸
|
|
2812
|
-
for (const [sid,
|
|
2819
|
+
for (const [sid, 记] of 闸门挂着) {
|
|
2813
2820
|
const 还要 = [...该挂].some((id) => 会话键(id) === sid)
|
|
2814
2821
|
if (还要) continue
|
|
2815
|
-
try { if (typeof off === 'function') off() } catch (error) {}
|
|
2822
|
+
try { if (记 && typeof 记.off === 'function') 记.off() } catch (error) {}
|
|
2816
2823
|
闸门挂着.delete(sid)
|
|
2817
2824
|
记账('回复门槛已卸下(' + 短id(sid) + ')')
|
|
2818
2825
|
}
|
|
@@ -2954,7 +2961,7 @@ export function apply(ctx) {
|
|
|
2954
2961
|
if (!m) continue
|
|
2955
2962
|
const 图数 = Array.isArray(m.images) ? m.images.length : 0
|
|
2956
2963
|
行们.push((起 + i + 1) + '. ' + 空间时间(m.time)
|
|
2957
|
-
+ (m.tid != null ? ' tid ' + String(m.tid) : '')
|
|
2964
|
+
+ (m.tid != null ? ' tid ' + JSON.stringify(String(m.tid)) : '')
|
|
2958
2965
|
+ ' 评论 ' + (Number(m.comment_num) || 0)
|
|
2959
2966
|
+ (m.is_private ? ' 私密' : '')
|
|
2960
2967
|
+ ' 图 ' + 图数 + ' 张'
|
|
@@ -2972,7 +2979,7 @@ export function apply(ctx) {
|
|
|
2972
2979
|
parameters: {
|
|
2973
2980
|
type: 'object',
|
|
2974
2981
|
properties: {
|
|
2975
|
-
tid: { type: '
|
|
2982
|
+
tid: { type: 'string', description: '说说的 tid:qq_space_list 里 tid 后面那一串,原样照抄' },
|
|
2976
2983
|
qq: { type: 'string', description: '这条说说属于谁的 QQ 号。不填 = 机器人自己的' },
|
|
2977
2984
|
num: { type: 'integer', minimum: 1, maximum: 50, description: '评论最多看几条,默认 20' },
|
|
2978
2985
|
pos: { type: 'integer', minimum: 0, description: '评论从第几条开始,默认 0' },
|
|
@@ -2983,8 +2990,12 @@ export function apply(ctx) {
|
|
|
2983
2990
|
output: 空间输出(),
|
|
2984
2991
|
async execute(args = {}) {
|
|
2985
2992
|
const 配置 = 读配置()
|
|
2986
|
-
|
|
2987
|
-
|
|
2993
|
+
// ⭐ 1.5.5:tid 是 24 位十六进制的一串字符,不是数字。
|
|
2994
|
+
// 以前这里写的是 integer + Math.round(Number()):模型照着「整数」去填就不加引号,
|
|
2995
|
+
// 写出来是个非法 JSON,整轮直接被判失败;就算写成数字串,Number() 也会丢精度。
|
|
2996
|
+
// 现在一律当字符串原样往下传。
|
|
2997
|
+
const tid = String(args.tid == null ? '' : args.tid).trim()
|
|
2998
|
+
if (!tid) return { ok: false, 说: '要给一个说说的 tid(从 qq_space_list 里拿,原样照抄)' }
|
|
2988
2999
|
const 条数 = Math.max(1, Math.min(Math.round(Number(args.num) || 20), 50))
|
|
2989
3000
|
const 起 = Math.max(0, Math.round(Number(args.pos) || 0))
|
|
2990
3001
|
const 体 = { tid, pos: 起, num: 条数 }
|
|
@@ -3125,6 +3136,11 @@ export function apply(ctx) {
|
|
|
3125
3136
|
// 0.2.2 起同一作用域不许重名注册,于是每次都抛 already registered,日志被刷爆。
|
|
3126
3137
|
const 已挂 = 空间挂着.get(sid)
|
|
3127
3138
|
if (已挂 && 已挂.agent === agent) continue
|
|
3139
|
+
// 实例换了:先把上一批摘干净再挂新的,别留两份
|
|
3140
|
+
if (已挂 && typeof 已挂.off === 'function') {
|
|
3141
|
+
try { 已挂.off() } catch (error) {}
|
|
3142
|
+
}
|
|
3143
|
+
空间挂着.delete(sid)
|
|
3128
3144
|
const 卸们 = []
|
|
3129
3145
|
let 已经有过 = 0
|
|
3130
3146
|
for (const 工具 of 做空间工具()) {
|
|
@@ -3856,6 +3872,23 @@ export function apply(ctx) {
|
|
|
3856
3872
|
}
|
|
3857
3873
|
}, 'qq-bridge: 轮询收 QQ 消息')
|
|
3858
3874
|
|
|
3875
|
+
// ⭐ 1.5.6:会话一建出来就当场挂,不等下一跳轮询。
|
|
3876
|
+
// 以前这两批工具只在「收消息那一跳」里顺带挂(默认 2 秒一次)。重启之后,
|
|
3877
|
+
// 第一句要是来得比那一跳快,那一轮的工具表就少几条 —— 前缀跟着变,
|
|
3878
|
+
// 整段历史按未缓存重算一次。DSH 有 agent/created,建好就通知,用它就没有空档。
|
|
3879
|
+
for (const 事件 of ['agent/created', 'agent/disposed']) {
|
|
3880
|
+
try {
|
|
3881
|
+
ctx.on(事件, () => {
|
|
3882
|
+
try {
|
|
3883
|
+
闸门心跳()
|
|
3884
|
+
空间工具心跳()
|
|
3885
|
+
} catch (error) {}
|
|
3886
|
+
})
|
|
3887
|
+
} catch (error) {
|
|
3888
|
+
记账('挂不上 ' + 事件 + '(不影响对话):' + String((error && error.message) || error))
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
|
|
3859
3892
|
// ⭐ 1.5.0:空间的两件定时活,共用一个 60 秒的 setInterval(定时说说 + 定时看一圈)。
|
|
3860
3893
|
// ⚠ 整跳都在 空间定时一跳 里各自 try/catch —— 抛一次错不能让后面的跳停掉。
|
|
3861
3894
|
// 宿主没给 setTimeout / setInterval 就安静跳过(跟上面 ctx.interval 不在一处,别混)。
|
package/package.json
CHANGED