@zaofan/dsh-qqbot 1.11.2 → 1.11.3
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/qqbot-settings.js
CHANGED
|
@@ -895,6 +895,14 @@ window.__ModuleLoader__.load({
|
|
|
895
895
|
context: function () { return fetch(q('context')).then(function (r) { return r.json() }).catch(function () { return null }) },
|
|
896
896
|
sessions: function () { return fetch(q('sessions')).then(function (r) { return r.json() }).catch(function () { return null }) },
|
|
897
897
|
history: function (n) { return fetch(q('history') + '&limit=' + (n || 20)).then(function (r) { return r.json() }).catch(function () { return null }) },
|
|
898
|
+
/**
|
|
899
|
+
* 当前会话 **AI 最后一个正文块**(2026-10-27)
|
|
900
|
+
* 不是 QQ 消息流水,是 agent 真正输出的那段文字。
|
|
901
|
+
* 实现:宿主 kernel.get('sessions').get(sid).deriveMessages() 从后往前找 assistant。
|
|
902
|
+
*/
|
|
903
|
+
lastAssistantText: function () {
|
|
904
|
+
return fetch(q('lastAssistantText')).then(function (r) { return r.json() }).catch(function () { return null })
|
|
905
|
+
},
|
|
898
906
|
members: function () { return fetch(q('members')).then(function (r) { return r.json() }).catch(function () { return null }) },
|
|
899
907
|
}
|
|
900
908
|
}
|
|
@@ -93,7 +93,8 @@ qqbotExt.dock.peerId / scope / ns
|
|
|
93
93
|
qqbotExt.dock.dataRoot / cwd
|
|
94
94
|
qqbotExt.dock.context() // 实例 + 会话信息
|
|
95
95
|
qqbotExt.dock.sessions() // 这个机器人管过哪些会话
|
|
96
|
-
qqbotExt.dock.history(n) // 当前会话最近 n
|
|
96
|
+
qqbotExt.dock.history(n) // 当前会话最近 n 条消息(QQ 消息流水)
|
|
97
|
+
qqbotExt.dock.lastAssistantText() // ★ AI 最后一个正文块(她真正输出的那段话)
|
|
97
98
|
qqbotExt.dock.members() // 群友台账
|
|
98
99
|
|
|
99
100
|
// 能力(与代码扩展对齐,走白名单 RPC)
|
|
@@ -37,10 +37,11 @@
|
|
|
37
37
|
|
|
38
38
|
<!-- 子标签 2:展示 dock 能拿到的会话数据(这是 dock 独有能力的演示) -->
|
|
39
39
|
<div class="pane" data-pane="ctx">
|
|
40
|
-
<div class="row"><span class="hint">下面这些是 dock 卡片独有的能力 ——
|
|
40
|
+
<div class="row"><span class="hint">下面这些是 dock 卡片独有的能力 —— 能直接读到当前实例和会话的真实数据。<br />
|
|
41
|
+
「读 AI 最后正文」取的是她 <b>最后一次输出的那段话</b>(不是 QQ 消息流水)。</span></div>
|
|
41
42
|
<div class="acts">
|
|
42
43
|
<button class="btn" id="ctxBtn">读上下文</button>
|
|
43
|
-
<button class="btn ghost" id="hisBtn"
|
|
44
|
+
<button class="btn ghost" id="hisBtn">读 AI 最后正文</button>
|
|
44
45
|
</div>
|
|
45
46
|
<pre class="info" id="info">点上面按钮看看</pre>
|
|
46
47
|
</div>
|
|
@@ -64,12 +64,13 @@
|
|
|
64
64
|
hisBtn.addEventListener('click', function () {
|
|
65
65
|
if (!qqbotExt.dock) return setInfo('这个卡片没有 dock 上下文')
|
|
66
66
|
setInfo('读取中…')
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
setInfo(
|
|
67
|
+
// ★ 2026-10-27(主人要求):读 **AI 最后一个正文块**,不是 QQ 消息流水。
|
|
68
|
+
// 实现抄 session_watch_lib.mjs 的 lastAssistantText():
|
|
69
|
+
// 宿主 kernel.get('sessions').get(sid).deriveMessages() 从后往前找 assistant。
|
|
70
|
+
qqbotExt.dock.lastAssistantText().then(function (r) {
|
|
71
|
+
if (!r) return setInfo('没有响应')
|
|
72
|
+
if (!r.ok) return setInfo('读不到:' + (r.reason || r.via || '未知') + (r.sid ? ('\nsid=' + r.sid) : ''))
|
|
73
|
+
setInfo('(AI 最后一段正文,' + r.text.length + ' 字符)\n\n' + r.text)
|
|
73
74
|
})
|
|
74
75
|
})
|
|
75
76
|
}
|
package/package.json
CHANGED
package/settings-host.js
CHANGED
|
@@ -5481,6 +5481,43 @@ const WHY_MAP = { busy: '目标会话回合活跃,已等待至回合结束仍超
|
|
|
5481
5481
|
return writeJson(res, 200, { ok: true, messages: rows });
|
|
5482
5482
|
}
|
|
5483
5483
|
|
|
5484
|
+
// ★ 2026-10-27(主人要求):取当前会话「AI 最后一个正文块」。
|
|
5485
|
+
// 原来卡片读的是 .qqbot/msg-history(QQ 消息流水),跟 AI 的正文不是一回事。
|
|
5486
|
+
// 实现抄 examples/ext-tools/lib/session_watch_lib.mjs 的 lastAssistantText():
|
|
5487
|
+
// 宿主 kernel.get('sessions').get(sid).deriveMessages() 从后往前找 assistant 角色。
|
|
5488
|
+
// (那条路还支持 turn/end 事件累积,但这里只要"最后一次的正文",直接取更省事。)
|
|
5489
|
+
if (what === 'lastAssistantText') {
|
|
5490
|
+
const sid = String(q?.get('sid') || '').trim();
|
|
5491
|
+
if (!sid) return writeJson(res, 200, { ok: false, reason: '缺 sid(当前会话 id)', text: '' });
|
|
5492
|
+
let text = '';
|
|
5493
|
+
let via = '';
|
|
5494
|
+
try {
|
|
5495
|
+
const sessions = ctx.get?.('sessions');
|
|
5496
|
+
const sess = sessions && typeof sessions.get === 'function' ? sessions.get(sid) : null;
|
|
5497
|
+
if (sess && typeof sess.deriveMessages === 'function') {
|
|
5498
|
+
const msgs = sess.deriveMessages() || [];
|
|
5499
|
+
for (let i = msgs.length - 1; i >= 0; i--) {
|
|
5500
|
+
const m = msgs[i];
|
|
5501
|
+
const role = String(m?.role ?? m?.type ?? '');
|
|
5502
|
+
if (!role.includes('assistant')) continue;
|
|
5503
|
+
// content 可能是字符串、数组(每项带 text)、或对象
|
|
5504
|
+
const c = m?.content;
|
|
5505
|
+
let t = '';
|
|
5506
|
+
if (typeof c === 'string') t = c;
|
|
5507
|
+
else if (Array.isArray(c)) t = c.map((x) => (typeof x === 'string' ? x : String(x?.text ?? ''))).join('');
|
|
5508
|
+
else if (c && typeof c === 'object') t = String(c.text ?? '');
|
|
5509
|
+
t = t.trim();
|
|
5510
|
+
if (t) { text = t; via = 'deriveMessages'; break; }
|
|
5511
|
+
}
|
|
5512
|
+
} else {
|
|
5513
|
+
via = 'sessions.get 拿不到会话';
|
|
5514
|
+
}
|
|
5515
|
+
} catch (e) {
|
|
5516
|
+
via = '异常: ' + (e instanceof Error ? e.message : String(e));
|
|
5517
|
+
}
|
|
5518
|
+
return writeJson(res, 200, { ok: !!text, text, via, sid });
|
|
5519
|
+
}
|
|
5520
|
+
|
|
5484
5521
|
if (what === 'members') {
|
|
5485
5522
|
// 群友台账(people-memo 落的那份)
|
|
5486
5523
|
let out = {};
|
|
@@ -5703,7 +5740,11 @@ const WHY_MAP = { busy: '目标会话回合活跃,已等待至回合结束仍超
|
|
|
5703
5740
|
dataRoot: dr,
|
|
5704
5741
|
logger: console,
|
|
5705
5742
|
selfName: id,
|
|
5706
|
-
kind
|
|
5743
|
+
// ★ 2026-10-27:kind 不能传 'ui' —— store 会落到 .qqbot-extensions/ui/data/,
|
|
5744
|
+
// 而 listExtUi 正是扫 ui/ 下每个子目录找 card.html,会把 data/ 当成一个扩展目录。
|
|
5745
|
+
// 用点开头:路径变成 .qqbot-extensions/.ui-data/data/<extId>.json,
|
|
5746
|
+
// 既不在 ui/ 下,也不会被 EXT_ID_RE(不允许 '.')当成扩展 id。
|
|
5747
|
+
kind: '.ui-data',
|
|
5707
5748
|
appId: String(viewOf(ctx.settings, capNs)?.value?.appId || ''),
|
|
5708
5749
|
owners: (() => {
|
|
5709
5750
|
try {
|