@jerryliang122/openclaw-qqbot 1.0.8 → 1.0.9
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/dist/index.cjs +214 -167
- package/dist/index.cjs.map +1 -1
- package/package.json +1 -1
- package/src/openclaw-plugin-sdk.d.ts +38 -2
- package/src/tools/platform.ts +86 -72
- package/src/tools/remind.ts +53 -42
- package/src/tools/secret-input.ts +112 -80
- package/src/tools/tool-session.ts +74 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工具执行时的会话路由解析(双层回退)
|
|
3
|
+
*
|
|
4
|
+
* 背景(2026-09-23 事故):qqbot_secret_input 等工具此前仅靠
|
|
5
|
+
* request-context(AsyncLocalStorage)获取当前会话目标。ALS 只在
|
|
6
|
+
* handleMessage → dispatchToOpenClaw 的异步子树内有效;openclaw 框架
|
|
7
|
+
* 经常把 agent turn 延迟到该子树之外执行——活动 turn 之后排队的
|
|
8
|
+
* followup/collect 批处理、框架自有定时器驱动的队列 drain 等。此时
|
|
9
|
+
* 工具执行处 ALS 为空,工具报「无法获取当前会话目标」直接失败。
|
|
10
|
+
*
|
|
11
|
+
* 修复:优先 ALS(逐消息精确,含 messageId/openId 供日志富化);
|
|
12
|
+
* ALS 缺失时回退到框架在工具工厂上下文里提供的 deliveryContext
|
|
13
|
+
* (openclaw 按当前 run 的 sessionCtx 派生的可信投递路由:
|
|
14
|
+
* { channel, to, accountId },qqbot 通道的 to 即规范目标地址
|
|
15
|
+
* qqbot:c2c:{openid} / qqbot:group:{group_openid})。
|
|
16
|
+
*
|
|
17
|
+
* 工厂注册形式:api.registerTool((ctx) => ({ ...tool }), { name })。
|
|
18
|
+
* 框架在装配工具面(或缓存描述符路径下的每次执行)时调用工厂,
|
|
19
|
+
* ctx 携带当次 run 的 deliveryContext——描述符缓存键包含
|
|
20
|
+
* deliveryContext,不会跨会话复用旧路由。
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { getRequestAccountId, getRequestTarget } from '../request-context.js';
|
|
24
|
+
|
|
25
|
+
/** 框架 deliveryContext 中本项目用到的字段(见 openclaw OpenClawPluginToolContext) */
|
|
26
|
+
export interface ToolDeliveryContext {
|
|
27
|
+
channel?: string;
|
|
28
|
+
to?: string;
|
|
29
|
+
accountId?: string;
|
|
30
|
+
threadId?: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** 解析出的会话路由 */
|
|
34
|
+
export interface ToolSessionRoute {
|
|
35
|
+
/** 规范目标地址:qqbot:c2c:{openid} / qqbot:group:{group_openid} */
|
|
36
|
+
target: string;
|
|
37
|
+
/** 账户 ID(多账户场景;可能为空,由调用方决定回退策略) */
|
|
38
|
+
accountId?: string;
|
|
39
|
+
/** 路由来源:request-context(ALS)优先,delivery-context(框架 run 级)回退 */
|
|
40
|
+
source: 'request-context' | 'delivery-context';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 解析当前工具调用所属的会话路由。
|
|
45
|
+
*
|
|
46
|
+
* 返回 undefined 表示当前 run 没有可识别的 QQ 会话来源
|
|
47
|
+
* (如 cron/定时任务、内部 UI 发起的 run)——调用方应返回明确错误。
|
|
48
|
+
*/
|
|
49
|
+
export function resolveToolSessionRoute(
|
|
50
|
+
delivery?: ToolDeliveryContext | null,
|
|
51
|
+
): ToolSessionRoute | undefined {
|
|
52
|
+
// 第一层:请求级 ALS(入站消息处理链路内,逐消息精确)
|
|
53
|
+
const alsTarget = getRequestTarget();
|
|
54
|
+
if (alsTarget) {
|
|
55
|
+
return {
|
|
56
|
+
target: alsTarget,
|
|
57
|
+
accountId: getRequestAccountId(),
|
|
58
|
+
source: 'request-context',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// 第二层:框架 run 级 deliveryContext(延迟/排队 turn 的回退)
|
|
63
|
+
const to = typeof delivery?.to === 'string' ? delivery.to.trim() : '';
|
|
64
|
+
if (!to) return undefined;
|
|
65
|
+
const channel = typeof delivery?.channel === 'string' ? delivery.channel.trim() : '';
|
|
66
|
+
// 防御:deliveryContext 属于其他通道(理论上不会发生)时不误认
|
|
67
|
+
if (channel && channel !== 'qqbot') return undefined;
|
|
68
|
+
if (!/^qqbot:(c2c|group|channel):/i.test(to)) return undefined;
|
|
69
|
+
return {
|
|
70
|
+
target: to,
|
|
71
|
+
accountId: delivery?.accountId,
|
|
72
|
+
source: 'delivery-context',
|
|
73
|
+
};
|
|
74
|
+
}
|