@ynhcj/xiaoyi 2.5.6 → 2.5.7
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/auth.d.ts +1 -1
- package/dist/channel.d.ts +59 -14
- package/dist/channel.js +142 -814
- package/dist/file-download.d.ts +17 -0
- package/dist/file-download.js +69 -0
- package/dist/heartbeat.d.ts +39 -0
- package/dist/heartbeat.js +102 -0
- package/dist/index.js +5 -5
- package/dist/push.d.ts +1 -1
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +2 -2
- package/dist/types.d.ts +74 -1
- package/dist/websocket.d.ts +17 -1
- package/dist/websocket.js +163 -13
- package/dist/xy-bot.d.ts +19 -0
- package/dist/xy-bot.js +277 -0
- package/dist/xy-client.d.ts +26 -0
- package/dist/xy-client.js +78 -0
- package/dist/xy-config.d.ts +18 -0
- package/dist/xy-config.js +37 -0
- package/dist/xy-formatter.d.ts +94 -0
- package/dist/xy-formatter.js +303 -0
- package/dist/xy-monitor.d.ts +17 -0
- package/dist/xy-monitor.js +187 -0
- package/dist/xy-parser.d.ts +49 -0
- package/dist/xy-parser.js +109 -0
- package/dist/xy-reply-dispatcher.d.ts +17 -0
- package/dist/xy-reply-dispatcher.js +308 -0
- package/dist/xy-tools/session-manager.d.ts +29 -0
- package/dist/xy-tools/session-manager.js +80 -0
- package/dist/xy-utils/config-manager.d.ts +26 -0
- package/dist/xy-utils/config-manager.js +61 -0
- package/dist/xy-utils/crypto.d.ts +8 -0
- package/dist/xy-utils/crypto.js +21 -0
- package/dist/xy-utils/logger.d.ts +6 -0
- package/dist/xy-utils/logger.js +37 -0
- package/dist/xy-utils/session.d.ts +34 -0
- package/dist/xy-utils/session.js +55 -0
- package/package.json +32 -17
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Download a file from URL to local path.
|
|
3
|
+
*/
|
|
4
|
+
export declare function downloadFile(url: string, destPath: string): Promise<void>;
|
|
5
|
+
/**
|
|
6
|
+
* Download files from A2A file parts.
|
|
7
|
+
* Returns array of local file paths.
|
|
8
|
+
*/
|
|
9
|
+
export declare function downloadFilesFromParts(fileParts: Array<{
|
|
10
|
+
name: string;
|
|
11
|
+
mimeType: string;
|
|
12
|
+
uri: string;
|
|
13
|
+
}>, tempDir?: string): Promise<Array<{
|
|
14
|
+
path: string;
|
|
15
|
+
name: string;
|
|
16
|
+
mimeType: string;
|
|
17
|
+
}>>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.downloadFile = downloadFile;
|
|
7
|
+
exports.downloadFilesFromParts = downloadFilesFromParts;
|
|
8
|
+
// File download utilities
|
|
9
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
10
|
+
const promises_1 = __importDefault(require("fs/promises"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const logger_js_1 = require("./xy-utils/logger.js");
|
|
13
|
+
/**
|
|
14
|
+
* Download a file from URL to local path.
|
|
15
|
+
*/
|
|
16
|
+
async function downloadFile(url, destPath) {
|
|
17
|
+
logger_js_1.logger.debug(`Downloading file from ${url} to ${destPath}`);
|
|
18
|
+
const controller = new AbortController();
|
|
19
|
+
const timeout = setTimeout(() => controller.abort(), 30000); // 30 seconds timeout
|
|
20
|
+
try {
|
|
21
|
+
const response = await (0, node_fetch_1.default)(url, { signal: controller.signal });
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
26
|
+
const buffer = Buffer.from(arrayBuffer);
|
|
27
|
+
await promises_1.default.writeFile(destPath, buffer);
|
|
28
|
+
logger_js_1.logger.debug(`File downloaded successfully: ${destPath}`);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (error.name === 'AbortError') {
|
|
32
|
+
logger_js_1.logger.error(`Download timeout (30s) for ${url}`);
|
|
33
|
+
throw new Error(`Download timeout after 30 seconds`);
|
|
34
|
+
}
|
|
35
|
+
logger_js_1.logger.error(`Failed to download file from ${url}:`, error);
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
clearTimeout(timeout);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Download files from A2A file parts.
|
|
44
|
+
* Returns array of local file paths.
|
|
45
|
+
*/
|
|
46
|
+
async function downloadFilesFromParts(fileParts, tempDir = "/tmp/xy_channel") {
|
|
47
|
+
// Create temp directory if it doesn't exist
|
|
48
|
+
await promises_1.default.mkdir(tempDir, { recursive: true });
|
|
49
|
+
const downloadedFiles = [];
|
|
50
|
+
for (const filePart of fileParts) {
|
|
51
|
+
const { name, mimeType, uri } = filePart;
|
|
52
|
+
// Generate safe file name
|
|
53
|
+
const safeName = name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
54
|
+
const destPath = path_1.default.join(tempDir, `${Date.now()}_${safeName}`);
|
|
55
|
+
try {
|
|
56
|
+
await downloadFile(uri, destPath);
|
|
57
|
+
downloadedFiles.push({
|
|
58
|
+
path: destPath,
|
|
59
|
+
name,
|
|
60
|
+
mimeType,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
logger_js_1.logger.error(`Failed to download file ${name}:`, error);
|
|
65
|
+
// Continue with other files
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return downloadedFiles;
|
|
69
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import WebSocket from "ws";
|
|
2
|
+
export interface HeartbeatConfig {
|
|
3
|
+
interval: number;
|
|
4
|
+
timeout: number;
|
|
5
|
+
message: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Manages heartbeat for a WebSocket connection.
|
|
9
|
+
* Supports both application-level and protocol-level heartbeats.
|
|
10
|
+
*/
|
|
11
|
+
export declare class HeartbeatManager {
|
|
12
|
+
private ws;
|
|
13
|
+
private config;
|
|
14
|
+
private onTimeout;
|
|
15
|
+
private serverName;
|
|
16
|
+
private onHeartbeatSuccess?;
|
|
17
|
+
private intervalTimer;
|
|
18
|
+
private timeoutTimer;
|
|
19
|
+
private lastPongTime;
|
|
20
|
+
private log;
|
|
21
|
+
private error;
|
|
22
|
+
constructor(ws: WebSocket, config: HeartbeatConfig, onTimeout: () => void, serverName?: string, logFn?: (msg: string, ...args: any[]) => void, errorFn?: (msg: string, ...args: any[]) => void, onHeartbeatSuccess?: () => void);
|
|
23
|
+
/**
|
|
24
|
+
* Start heartbeat monitoring.
|
|
25
|
+
*/
|
|
26
|
+
start(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Stop heartbeat monitoring.
|
|
29
|
+
*/
|
|
30
|
+
stop(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Send a heartbeat ping.
|
|
33
|
+
*/
|
|
34
|
+
private sendHeartbeat;
|
|
35
|
+
/**
|
|
36
|
+
* Check if connection is healthy based on last pong time.
|
|
37
|
+
*/
|
|
38
|
+
isHealthy(): boolean;
|
|
39
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.HeartbeatManager = void 0;
|
|
7
|
+
// Heartbeat management for WebSocket connections
|
|
8
|
+
const ws_1 = __importDefault(require("ws"));
|
|
9
|
+
/**
|
|
10
|
+
* Manages heartbeat for a WebSocket connection.
|
|
11
|
+
* Supports both application-level and protocol-level heartbeats.
|
|
12
|
+
*/
|
|
13
|
+
class HeartbeatManager {
|
|
14
|
+
constructor(ws, config, onTimeout, serverName = "unknown", logFn, errorFn, onHeartbeatSuccess // ✅ 心跳成功回调,向 OpenClaw 报告健康状态
|
|
15
|
+
) {
|
|
16
|
+
this.ws = ws;
|
|
17
|
+
this.config = config;
|
|
18
|
+
this.onTimeout = onTimeout;
|
|
19
|
+
this.serverName = serverName;
|
|
20
|
+
this.onHeartbeatSuccess = onHeartbeatSuccess;
|
|
21
|
+
this.intervalTimer = null;
|
|
22
|
+
this.timeoutTimer = null;
|
|
23
|
+
this.lastPongTime = 0;
|
|
24
|
+
this.log = logFn ?? console.log;
|
|
25
|
+
this.error = errorFn ?? console.error;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Start heartbeat monitoring.
|
|
29
|
+
*/
|
|
30
|
+
start() {
|
|
31
|
+
this.stop(); // Clear any existing timers
|
|
32
|
+
this.lastPongTime = Date.now();
|
|
33
|
+
// Setup ping/pong for protocol-level heartbeat
|
|
34
|
+
this.ws.on("pong", () => {
|
|
35
|
+
this.lastPongTime = Date.now();
|
|
36
|
+
if (this.timeoutTimer) {
|
|
37
|
+
clearTimeout(this.timeoutTimer);
|
|
38
|
+
this.timeoutTimer = null;
|
|
39
|
+
}
|
|
40
|
+
// ✅ Report health: heartbeat successful - notify OpenClaw framework
|
|
41
|
+
this.onHeartbeatSuccess?.();
|
|
42
|
+
this.log(`[${this.serverName}] Heartbeat pong received, health reported to OpenClaw`);
|
|
43
|
+
});
|
|
44
|
+
// Start interval timer
|
|
45
|
+
this.intervalTimer = setInterval(() => {
|
|
46
|
+
this.sendHeartbeat();
|
|
47
|
+
}, this.config.interval);
|
|
48
|
+
this.log(`[${this.serverName}] Heartbeat started: interval=${this.config.interval}ms, timeout=${this.config.timeout}ms`);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Stop heartbeat monitoring.
|
|
52
|
+
*/
|
|
53
|
+
stop() {
|
|
54
|
+
if (this.intervalTimer) {
|
|
55
|
+
clearInterval(this.intervalTimer);
|
|
56
|
+
this.intervalTimer = null;
|
|
57
|
+
}
|
|
58
|
+
if (this.timeoutTimer) {
|
|
59
|
+
clearTimeout(this.timeoutTimer);
|
|
60
|
+
this.timeoutTimer = null;
|
|
61
|
+
}
|
|
62
|
+
// Remove pong listener
|
|
63
|
+
this.ws.off("pong", () => { });
|
|
64
|
+
this.log(`[${this.serverName}] Heartbeat stopped`);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Send a heartbeat ping.
|
|
68
|
+
*/
|
|
69
|
+
sendHeartbeat() {
|
|
70
|
+
if (this.ws.readyState !== ws_1.default.OPEN) {
|
|
71
|
+
console.warn(`[${this.serverName}] Cannot send heartbeat: WebSocket not open`);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
try {
|
|
75
|
+
// Send application-level heartbeat message
|
|
76
|
+
this.log(`[${this.serverName}] Sending heartbeat frame:`, this.config.message.substring(0, 100));
|
|
77
|
+
this.ws.send(this.config.message);
|
|
78
|
+
// Send protocol-level ping
|
|
79
|
+
this.ws.ping();
|
|
80
|
+
this.log(`[${this.serverName}] Protocol-level ping sent`);
|
|
81
|
+
// Setup timeout timer
|
|
82
|
+
this.timeoutTimer = setTimeout(() => {
|
|
83
|
+
this.error(`[${this.serverName}] Heartbeat timeout - no pong received`);
|
|
84
|
+
this.onTimeout();
|
|
85
|
+
}, this.config.timeout);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
this.error(`[${this.serverName}] Failed to send heartbeat:`, error);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check if connection is healthy based on last pong time.
|
|
93
|
+
*/
|
|
94
|
+
isHealthy() {
|
|
95
|
+
if (this.lastPongTime === 0) {
|
|
96
|
+
return true; // Not started yet
|
|
97
|
+
}
|
|
98
|
+
const timeSinceLastPong = Date.now() - this.lastPongTime;
|
|
99
|
+
return timeSinceLastPong < this.config.interval + this.config.timeout;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
exports.HeartbeatManager = HeartbeatManager;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const
|
|
3
|
+
const channel_js_1 = require("./channel.js");
|
|
4
|
+
const runtime_js_1 = require("./runtime.js");
|
|
5
5
|
/**
|
|
6
6
|
* XiaoYi Channel Plugin for OpenClaw
|
|
7
7
|
*
|
|
@@ -30,10 +30,10 @@ const plugin = {
|
|
|
30
30
|
register(api) {
|
|
31
31
|
console.log("XiaoYi: register() called - START");
|
|
32
32
|
// Set runtime for managing WebSocket connections
|
|
33
|
-
(0,
|
|
33
|
+
(0, runtime_js_1.setXiaoYiRuntime)(api.runtime);
|
|
34
34
|
console.log("XiaoYi: setXiaoYiRuntime() completed");
|
|
35
35
|
// Clean up any existing connections from previous plugin loads
|
|
36
|
-
const runtime = require("./runtime").getXiaoYiRuntime();
|
|
36
|
+
const runtime = require("./runtime.js").getXiaoYiRuntime();
|
|
37
37
|
console.log(`XiaoYi: Got runtime instance: ${runtime.getInstanceId()}, isConnected: ${runtime.isConnected()}`);
|
|
38
38
|
if (runtime.isConnected()) {
|
|
39
39
|
console.log("XiaoYi: Cleaning up existing connection from previous load");
|
|
@@ -41,7 +41,7 @@ const plugin = {
|
|
|
41
41
|
}
|
|
42
42
|
// Register the channel plugin
|
|
43
43
|
console.log("XiaoYi: About to call registerChannel()");
|
|
44
|
-
api.registerChannel({ plugin:
|
|
44
|
+
api.registerChannel({ plugin: channel_js_1.xiaoyiPlugin });
|
|
45
45
|
console.log("XiaoYi: registerChannel() completed");
|
|
46
46
|
console.log("XiaoYi channel plugin registered - END");
|
|
47
47
|
},
|
package/dist/push.d.ts
CHANGED
package/dist/runtime.d.ts
CHANGED
package/dist/runtime.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.XiaoYiRuntime = void 0;
|
|
4
4
|
exports.getXiaoYiRuntime = getXiaoYiRuntime;
|
|
5
5
|
exports.setXiaoYiRuntime = setXiaoYiRuntime;
|
|
6
|
-
const
|
|
6
|
+
const websocket_js_1 = require("./websocket.js");
|
|
7
7
|
/**
|
|
8
8
|
* Default timeout configuration
|
|
9
9
|
*/
|
|
@@ -64,7 +64,7 @@ class XiaoYiRuntime {
|
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
66
|
this.config = config;
|
|
67
|
-
const manager = new
|
|
67
|
+
const manager = new websocket_js_1.XiaoYiWebSocketManager(config);
|
|
68
68
|
// Setup basic event handlers (message handling is done in channel.ts)
|
|
69
69
|
manager.on("error", (error) => {
|
|
70
70
|
console.error("XiaoYi channel error:", error);
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,69 @@
|
|
|
1
|
+
export interface A2AJsonRpcRequest {
|
|
2
|
+
jsonrpc: "2.0";
|
|
3
|
+
method: string;
|
|
4
|
+
params: A2ARequestParams;
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
7
|
+
export interface A2ARequestParams {
|
|
8
|
+
id: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
agentLoginSessionId?: string;
|
|
11
|
+
message: A2AMessage;
|
|
12
|
+
}
|
|
13
|
+
export interface A2AMessage {
|
|
14
|
+
role: "user" | "assistant" | "system";
|
|
15
|
+
parts: A2AMessagePart[];
|
|
16
|
+
}
|
|
17
|
+
export type A2AMessagePart = A2ATextPart | A2AFilePart | A2ADataPart;
|
|
18
|
+
export interface A2ATextPart {
|
|
19
|
+
kind: "text";
|
|
20
|
+
text: string;
|
|
21
|
+
}
|
|
22
|
+
export interface A2AFilePart {
|
|
23
|
+
kind: "file";
|
|
24
|
+
file: {
|
|
25
|
+
name: string;
|
|
26
|
+
mimeType: string;
|
|
27
|
+
uri: string;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export interface A2ADataPart {
|
|
31
|
+
kind: "data";
|
|
32
|
+
data: {
|
|
33
|
+
event?: A2ADataEvent;
|
|
34
|
+
variables?: {
|
|
35
|
+
systemVariables?: {
|
|
36
|
+
push_id?: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
[key: string]: any;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface A2ADataEvent {
|
|
43
|
+
intentName: string;
|
|
44
|
+
outputs: Record<string, any>;
|
|
45
|
+
status: "success" | "failed";
|
|
46
|
+
}
|
|
47
|
+
export interface A2AReasoningTextPart {
|
|
48
|
+
kind: "reasoningText";
|
|
49
|
+
reasoningText: string;
|
|
50
|
+
}
|
|
51
|
+
export interface A2ACommandPart {
|
|
52
|
+
kind: "command";
|
|
53
|
+
command: A2ACommand;
|
|
54
|
+
}
|
|
55
|
+
export interface A2ACommand {
|
|
56
|
+
header: {
|
|
57
|
+
namespace: string;
|
|
58
|
+
name: string;
|
|
59
|
+
};
|
|
60
|
+
payload: Record<string, any>;
|
|
61
|
+
}
|
|
62
|
+
export type A2AArtifactPart = A2ATextPart | A2ADataPart | A2ACommandPart | A2AReasoningTextPart;
|
|
63
|
+
export interface A2AArtifact {
|
|
64
|
+
artifactId: string;
|
|
65
|
+
parts: A2AArtifactPart[];
|
|
66
|
+
}
|
|
1
67
|
export interface A2ARequestMessage {
|
|
2
68
|
agentId: string;
|
|
3
69
|
jsonrpc: "2.0";
|
|
@@ -75,8 +141,9 @@ export interface A2ATaskArtifactUpdateEvent {
|
|
|
75
141
|
artifact: {
|
|
76
142
|
artifactId: string;
|
|
77
143
|
parts: Array<{
|
|
78
|
-
kind: "text" | "file" | "data";
|
|
144
|
+
kind: "text" | "file" | "data" | "reasoningText";
|
|
79
145
|
text?: string;
|
|
146
|
+
reasoningText?: string;
|
|
80
147
|
file?: {
|
|
81
148
|
name: string;
|
|
82
149
|
mimeType: string;
|
|
@@ -205,3 +272,9 @@ export interface SessionCleanupState {
|
|
|
205
272
|
reason: 'user_cleared' | 'timeout' | 'error';
|
|
206
273
|
accumulatedText?: string;
|
|
207
274
|
}
|
|
275
|
+
export interface SessionBinding {
|
|
276
|
+
sessionId: string;
|
|
277
|
+
server: ServerIdentifier;
|
|
278
|
+
boundAt: number;
|
|
279
|
+
}
|
|
280
|
+
export type ServerIdentifier = 'server1' | 'server2';
|
package/dist/websocket.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { EventEmitter } from "events";
|
|
2
|
-
import { A2AResponseMessage, WebSocketConnectionState, XiaoYiChannelConfig, ServerId, ServerConnectionState, SessionCleanupState } from "./types";
|
|
2
|
+
import { A2AResponseMessage, OutboundWebSocketMessage, WebSocketConnectionState, XiaoYiChannelConfig, ServerId, ServerConnectionState, SessionCleanupState } from "./types.js";
|
|
3
3
|
export declare class XiaoYiWebSocketManager extends EventEmitter {
|
|
4
4
|
private ws1;
|
|
5
5
|
private ws2;
|
|
@@ -13,13 +13,21 @@ export declare class XiaoYiWebSocketManager extends EventEmitter {
|
|
|
13
13
|
private heartbeatTimeout1?;
|
|
14
14
|
private heartbeatTimeout2?;
|
|
15
15
|
private appHeartbeatInterval?;
|
|
16
|
+
private heartbeat1?;
|
|
17
|
+
private heartbeat2?;
|
|
16
18
|
private reconnectTimeout1?;
|
|
17
19
|
private reconnectTimeout2?;
|
|
18
20
|
private stableConnectionTimer1?;
|
|
19
21
|
private stableConnectionTimer2?;
|
|
20
22
|
private static readonly STABLE_CONNECTION_THRESHOLD;
|
|
21
23
|
private activeTasks;
|
|
24
|
+
private onHealthEvent?;
|
|
22
25
|
constructor(config: XiaoYiChannelConfig);
|
|
26
|
+
/**
|
|
27
|
+
* Set health event callback to report activity to OpenClaw framework.
|
|
28
|
+
* This callback is invoked on heartbeat success to update lastEventAt.
|
|
29
|
+
*/
|
|
30
|
+
setHealthEventCallback(callback: () => void): void;
|
|
23
31
|
/**
|
|
24
32
|
* Check if URL is wss + IP format (skip certificate verification)
|
|
25
33
|
*/
|
|
@@ -93,6 +101,14 @@ export declare class XiaoYiWebSocketManager extends EventEmitter {
|
|
|
93
101
|
* TODO: 实现实际的推送消息发送逻辑
|
|
94
102
|
*/
|
|
95
103
|
sendPushMessage(sessionId: string, message: string): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Send an outbound WebSocket message directly.
|
|
106
|
+
* This is a low-level method that sends a pre-formatted OutboundWebSocketMessage.
|
|
107
|
+
*
|
|
108
|
+
* @param sessionId - Session ID for routing
|
|
109
|
+
* @param message - Pre-formatted outbound message
|
|
110
|
+
*/
|
|
111
|
+
sendMessage(sessionId: string, message: OutboundWebSocketMessage): Promise<void>;
|
|
96
112
|
/**
|
|
97
113
|
* Send tasks cancel response to specific server
|
|
98
114
|
*/
|