Files
wechat-access-unqclawed/common/agent-events.ts
HenryXiaoYang ba754ccc31 feat: add WeChat QR code login and AGP WebSocket channel plugin
- Auth module: WeChat OAuth2 scan-to-login flow with terminal QR code
- Token persistence to ~/.openclaw/wechat-access-auth.json (chmod 600)
- Token resolution: config > saved state > interactive login
- Invite code verification (configurable bypass)
- Production/test environment support
- AGP WebSocket client with heartbeat, reconnect, wake detection
- Message handler: Agent dispatch with streaming text and tool calls
- Random device GUID generation (persisted, no real machine ID)
2026-03-10 02:29:06 +08:00

49 lines
1.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { onAgentEvent as OnAgentEventType } from "openclaw/plugin-sdk";
export type AgentEventStream = "lifecycle" | "tool" | "assistant" | "error" | (string & {});
export type AgentEventPayload = {
runId: string;
seq: number;
stream: AgentEventStream;
ts: number;
data: Record<string, unknown>;
sessionKey?: string;
};
// 动态导入,兼容 openclaw 未导出该函数的情况
let _onAgentEvent: typeof OnAgentEventType | undefined;
// SDK 加载完成的 Promise确保只加载一次
const sdkReady: Promise<typeof OnAgentEventType | undefined> = (async () => {
try {
const sdk = await import("openclaw/plugin-sdk");
if (typeof sdk.onAgentEvent === "function") {
_onAgentEvent = sdk.onAgentEvent;
}
} catch {
// ignore
}
return _onAgentEvent;
})();
/**
* 注册 Agent 事件监听器。
*
* 修复了原版的时序问题:原版使用 loadOnAgentEvent().then() 异步注册,
* 导致在 dispatchReplyWithBufferedBlockDispatcher 调用之前注册的监听器
* 实际上在 Agent 开始产生事件时还未真正挂载,造成事件全部丢失。
*
* 新版通过 await sdkReady 确保 SDK 加载完成后再注册监听器,
* 调用方需要 await 此函数返回的 Promise再调用 dispatchReply。
*/
export const onAgentEvent = async (
listener: Parameters<typeof OnAgentEventType>[0]
): Promise<() => boolean> => {
const fn = await sdkReady;
if (fn) {
const unsubscribe = fn(listener);
return unsubscribe;
}
return () => false;
};