@ynhcj/xiaoyi-channel 0.0.39-beta → 0.0.41-beta
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/src/bot.js +17 -13
- package/dist/src/channel.js +5 -4
- package/dist/src/client.js +11 -24
- package/dist/src/config.js +2 -2
- package/dist/src/monitor.js +12 -0
- package/dist/src/outbound.js +122 -88
- package/dist/src/push.d.ts +7 -1
- package/dist/src/push.js +22 -7
- package/dist/src/tools/search-photo-gallery-tool.js +30 -2
- package/dist/src/tools/view-push-result-tool.d.ts +5 -0
- package/dist/src/tools/view-push-result-tool.js +118 -0
- package/dist/src/tools/xiaoyi-collection-tool.d.ts +5 -0
- package/dist/src/tools/xiaoyi-collection-tool.js +190 -0
- package/dist/src/trigger-handler.d.ts +19 -0
- package/dist/src/trigger-handler.js +91 -0
- package/dist/src/types.d.ts +1 -8
- package/dist/src/types.js +4 -0
- package/dist/src/utils/pushdata-manager.d.ts +28 -0
- package/dist/src/utils/pushdata-manager.js +171 -0
- package/dist/src/utils/pushid-manager.d.ts +12 -0
- package/dist/src/utils/pushid-manager.js +105 -0
- package/dist/src/websocket.d.ts +25 -31
- package/dist/src/websocket.js +218 -270
- package/package.json +1 -1
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// pushId 持久化管理器
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
import { logger } from "./logger.js";
|
|
5
|
+
const PUSHID_LIST_FILE = "/home/sandbox/.openclaw/pushIdList.json";
|
|
6
|
+
/**
|
|
7
|
+
* 确保目录存在
|
|
8
|
+
*/
|
|
9
|
+
async function ensureDirectoryExists(filePath) {
|
|
10
|
+
const dir = path.dirname(filePath);
|
|
11
|
+
try {
|
|
12
|
+
await fs.mkdir(dir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
logger.error(`[PushIdManager] Failed to create directory ${dir}:`, error);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* 读取 pushId 列表
|
|
20
|
+
*/
|
|
21
|
+
async function readPushIdList() {
|
|
22
|
+
try {
|
|
23
|
+
await ensureDirectoryExists(PUSHID_LIST_FILE);
|
|
24
|
+
const content = await fs.readFile(PUSHID_LIST_FILE, "utf-8");
|
|
25
|
+
const list = JSON.parse(content);
|
|
26
|
+
if (!Array.isArray(list)) {
|
|
27
|
+
logger.warn(`[PushIdManager] pushIdList.json is not an array, returning empty array`);
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
return list;
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
if (error.code === "ENOENT") {
|
|
34
|
+
// 文件不存在,返回空数组
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
logger.error(`[PushIdManager] Failed to read pushIdList:`, error);
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 写入 pushId 列表
|
|
43
|
+
*/
|
|
44
|
+
async function writePushIdList(list) {
|
|
45
|
+
try {
|
|
46
|
+
await ensureDirectoryExists(PUSHID_LIST_FILE);
|
|
47
|
+
await fs.writeFile(PUSHID_LIST_FILE, JSON.stringify(list, null, 2), "utf-8");
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
logger.error(`[PushIdManager] Failed to write pushIdList:`, error);
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 添加新的 pushId(去重)
|
|
56
|
+
*/
|
|
57
|
+
export async function addPushId(pushId) {
|
|
58
|
+
if (!pushId || typeof pushId !== "string") {
|
|
59
|
+
logger.warn(`[PushIdManager] Invalid pushId: ${pushId}`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
try {
|
|
63
|
+
const list = await readPushIdList();
|
|
64
|
+
// 检查是否已存在
|
|
65
|
+
if (list.includes(pushId)) {
|
|
66
|
+
logger.log(`[PushIdManager] pushId already exists: ${pushId.substring(0, 20)}...`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// 添加新 pushId
|
|
70
|
+
list.push(pushId);
|
|
71
|
+
await writePushIdList(list);
|
|
72
|
+
logger.log(`[PushIdManager] ✅ Added new pushId: ${pushId.substring(0, 20)}...`);
|
|
73
|
+
logger.log(`[PushIdManager] - Total pushIds: ${list.length}`);
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
logger.error(`[PushIdManager] Failed to add pushId:`, error);
|
|
77
|
+
// 不抛出异常,避免影响主流程
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 获取所有 pushId
|
|
82
|
+
*/
|
|
83
|
+
export async function getAllPushIds() {
|
|
84
|
+
try {
|
|
85
|
+
const list = await readPushIdList();
|
|
86
|
+
logger.log(`[PushIdManager] Retrieved ${list.length} pushIds`);
|
|
87
|
+
return list;
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
logger.error(`[PushIdManager] Failed to get all pushIds:`, error);
|
|
91
|
+
return [];
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 清空所有 pushId(用于测试或重置)
|
|
96
|
+
*/
|
|
97
|
+
export async function clearAllPushIds() {
|
|
98
|
+
try {
|
|
99
|
+
await writePushIdList([]);
|
|
100
|
+
logger.log(`[PushIdManager] Cleared all pushIds`);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
logger.error(`[PushIdManager] Failed to clear pushIds:`, error);
|
|
104
|
+
}
|
|
105
|
+
}
|
package/dist/src/websocket.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { EventEmitter } from "events";
|
|
|
2
2
|
import type { RuntimeEnv } from "openclaw/plugin-sdk";
|
|
3
3
|
import type { XYChannelConfig, OutboundWebSocketMessage } from "./types.js";
|
|
4
4
|
/**
|
|
5
|
-
* Diagnostics for
|
|
5
|
+
* Diagnostics for WebSocket connection
|
|
6
6
|
*/
|
|
7
7
|
export interface ConnectionDiagnostic {
|
|
8
8
|
exists: boolean;
|
|
@@ -21,35 +21,30 @@ export interface ConnectionDiagnostic {
|
|
|
21
21
|
*/
|
|
22
22
|
export interface ManagerDiagnostics {
|
|
23
23
|
cacheKey: string;
|
|
24
|
-
|
|
25
|
-
server2: ConnectionDiagnostic;
|
|
24
|
+
connection: ConnectionDiagnostic;
|
|
26
25
|
isShuttingDown: boolean;
|
|
27
26
|
totalEventListeners: number;
|
|
28
27
|
}
|
|
29
28
|
/**
|
|
30
|
-
* Manages
|
|
31
|
-
* Implements session-to-server binding for message routing.
|
|
29
|
+
* Manages single WebSocket connection to XY server.
|
|
32
30
|
*
|
|
33
31
|
* Events:
|
|
34
|
-
* - 'message': (message: A2AJsonRpcRequest, sessionId: string
|
|
32
|
+
* - 'message': (message: A2AJsonRpcRequest, sessionId: string) => void
|
|
35
33
|
* - 'data-event': (event: A2ADataEvent) => void
|
|
36
34
|
* - 'gui-agent-response': (event: any) => void
|
|
37
|
-
* - '
|
|
38
|
-
* - '
|
|
39
|
-
* - '
|
|
40
|
-
* - '
|
|
35
|
+
* - 'trigger-event': (event: any) => void
|
|
36
|
+
* - 'connected': () => void
|
|
37
|
+
* - 'disconnected': () => void
|
|
38
|
+
* - 'error': (error: Error) => void
|
|
39
|
+
* - 'ready': () => void
|
|
41
40
|
*/
|
|
42
41
|
export declare class XYWebSocketManager extends EventEmitter {
|
|
43
42
|
private config;
|
|
44
43
|
private runtime?;
|
|
45
|
-
private
|
|
46
|
-
private
|
|
47
|
-
private
|
|
48
|
-
private
|
|
49
|
-
private heartbeat1;
|
|
50
|
-
private heartbeat2;
|
|
51
|
-
private reconnectTimer1;
|
|
52
|
-
private reconnectTimer2;
|
|
44
|
+
private ws;
|
|
45
|
+
private state;
|
|
46
|
+
private heartbeat;
|
|
47
|
+
private reconnectTimer;
|
|
53
48
|
private isShuttingDown;
|
|
54
49
|
private log;
|
|
55
50
|
private error;
|
|
@@ -64,45 +59,44 @@ export declare class XYWebSocketManager extends EventEmitter {
|
|
|
64
59
|
*/
|
|
65
60
|
isConfigMatch(config: XYChannelConfig): boolean;
|
|
66
61
|
/**
|
|
67
|
-
* Connect to
|
|
62
|
+
* Connect to WebSocket server.
|
|
68
63
|
* Does not throw error if connection fails - logs warning instead.
|
|
69
64
|
*/
|
|
70
65
|
connect(): Promise<void>;
|
|
71
66
|
/**
|
|
72
|
-
* Disconnect from
|
|
67
|
+
* Disconnect from WebSocket server.
|
|
73
68
|
*/
|
|
74
69
|
disconnect(): void;
|
|
75
70
|
/**
|
|
76
|
-
* Send a message to the
|
|
71
|
+
* Send a message to the server.
|
|
77
72
|
*/
|
|
78
73
|
sendMessage(sessionId: string, message: OutboundWebSocketMessage): Promise<void>;
|
|
79
74
|
/**
|
|
80
|
-
* Check if
|
|
75
|
+
* Check if server is ready.
|
|
81
76
|
*/
|
|
82
77
|
isReady(): boolean;
|
|
83
78
|
/**
|
|
84
79
|
* Get detailed connection diagnostics for monitoring and debugging.
|
|
85
|
-
* Helps identify orphan connections and connection leaks.
|
|
86
80
|
*/
|
|
87
81
|
getConnectionDiagnostics(): ManagerDiagnostics;
|
|
88
82
|
/**
|
|
89
|
-
* Get diagnostic info for
|
|
83
|
+
* Get diagnostic info for the connection.
|
|
90
84
|
*/
|
|
91
|
-
private
|
|
85
|
+
private getConnectionDiagnostic;
|
|
92
86
|
/**
|
|
93
|
-
*
|
|
87
|
+
* Clean up connection without triggering reconnection.
|
|
94
88
|
*/
|
|
95
|
-
private
|
|
89
|
+
private cleanupConnection;
|
|
96
90
|
/**
|
|
97
|
-
*
|
|
91
|
+
* Connect to server.
|
|
98
92
|
*/
|
|
99
|
-
private
|
|
93
|
+
private connectServer;
|
|
100
94
|
/**
|
|
101
95
|
* Send init message to server.
|
|
102
96
|
*/
|
|
103
97
|
private sendInitMessage;
|
|
104
98
|
/**
|
|
105
|
-
* Start heartbeat
|
|
99
|
+
* Start heartbeat.
|
|
106
100
|
*/
|
|
107
101
|
private startHeartbeat;
|
|
108
102
|
/**
|
|
@@ -118,7 +112,7 @@ export declare class XYWebSocketManager extends EventEmitter {
|
|
|
118
112
|
*/
|
|
119
113
|
private handleError;
|
|
120
114
|
/**
|
|
121
|
-
* Reconnect
|
|
115
|
+
* Reconnect with exponential backoff.
|
|
122
116
|
*/
|
|
123
117
|
private reconnectServer;
|
|
124
118
|
}
|