@ynhcj/xiaoyi-channel 0.0.155-beta → 0.0.157-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/cron-query-handler.d.ts +17 -0
- package/dist/src/cron-query-handler.js +101 -0
- package/dist/src/formatter.d.ts +2 -0
- package/dist/src/formatter.js +1 -1
- package/dist/src/monitor.js +9 -0
- package/dist/src/push.d.ts +6 -1
- package/dist/src/push.js +16 -3
- package/dist/src/self-evolution-handler.js +1 -1
- package/dist/src/websocket.js +19 -1
- package/package.json +1 -2
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type CronQueryAction = "list" | "status" | "runs" | "add" | "update" | "remove" | "run";
|
|
2
|
+
export interface CronQueryEventContext {
|
|
3
|
+
action: CronQueryAction;
|
|
4
|
+
jobId?: string;
|
|
5
|
+
params?: Record<string, unknown>;
|
|
6
|
+
/** Original A2A message fields for routing the response. */
|
|
7
|
+
sessionId?: string;
|
|
8
|
+
taskId?: string;
|
|
9
|
+
messageId?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Handle a cron-query-event.
|
|
13
|
+
*
|
|
14
|
+
* Calls the Gateway cron RPC and sends the result back through sendCommand
|
|
15
|
+
* as a System.CronQuery command with the full result object in payload.ans.
|
|
16
|
+
*/
|
|
17
|
+
export declare function handleCronQueryEvent(context: CronQueryEventContext, cfg?: unknown): Promise<void>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
// Cron query event handler.
|
|
2
|
+
// Listens for cron-query-event from the WebSocket manager,
|
|
3
|
+
// calls Gateway cron RPC via callGatewayTool, and sends the
|
|
4
|
+
// result back to the client via sendCommand as a System.CronQuery
|
|
5
|
+
// command with the result in payload.ans.
|
|
6
|
+
import { callGatewayTool } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
7
|
+
import { sendCommand } from "./formatter.js";
|
|
8
|
+
import { resolveXYConfig } from "./config.js";
|
|
9
|
+
import { logger } from "./utils/logger.js";
|
|
10
|
+
const GATEWAY_TIMEOUT_MS = 60_000;
|
|
11
|
+
/**
|
|
12
|
+
* Handle a cron-query-event.
|
|
13
|
+
*
|
|
14
|
+
* Calls the Gateway cron RPC and sends the result back through sendCommand
|
|
15
|
+
* as a System.CronQuery command with the full result object in payload.ans.
|
|
16
|
+
*/
|
|
17
|
+
export async function handleCronQueryEvent(context, cfg) {
|
|
18
|
+
const { action, jobId, params, sessionId, taskId, messageId } = context;
|
|
19
|
+
logger.log(`[CRON-QUERY] Received event: action=${action}, jobId=${jobId ?? "(none)"}`);
|
|
20
|
+
let result;
|
|
21
|
+
let error;
|
|
22
|
+
try {
|
|
23
|
+
switch (action) {
|
|
24
|
+
case "list":
|
|
25
|
+
result = await callGatewayTool("cron.list", { timeoutMs: GATEWAY_TIMEOUT_MS }, params ?? {});
|
|
26
|
+
break;
|
|
27
|
+
case "status":
|
|
28
|
+
result = await callGatewayTool("cron.status", { timeoutMs: GATEWAY_TIMEOUT_MS }, {});
|
|
29
|
+
break;
|
|
30
|
+
case "runs":
|
|
31
|
+
result = await callGatewayTool("cron.runs", { timeoutMs: GATEWAY_TIMEOUT_MS }, {
|
|
32
|
+
jobId,
|
|
33
|
+
...params,
|
|
34
|
+
});
|
|
35
|
+
break;
|
|
36
|
+
case "add":
|
|
37
|
+
result = await callGatewayTool("cron.add", { timeoutMs: GATEWAY_TIMEOUT_MS }, params ?? {});
|
|
38
|
+
break;
|
|
39
|
+
case "update":
|
|
40
|
+
result = await callGatewayTool("cron.update", { timeoutMs: GATEWAY_TIMEOUT_MS }, {
|
|
41
|
+
jobId,
|
|
42
|
+
...params,
|
|
43
|
+
});
|
|
44
|
+
break;
|
|
45
|
+
case "remove":
|
|
46
|
+
result = await callGatewayTool("cron.remove", { timeoutMs: GATEWAY_TIMEOUT_MS }, {
|
|
47
|
+
jobId,
|
|
48
|
+
});
|
|
49
|
+
break;
|
|
50
|
+
case "run":
|
|
51
|
+
result = await callGatewayTool("cron.run", { timeoutMs: GATEWAY_TIMEOUT_MS }, {
|
|
52
|
+
jobId,
|
|
53
|
+
mode: "force",
|
|
54
|
+
...params,
|
|
55
|
+
});
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
error = `Unknown action: ${context.action}`;
|
|
59
|
+
logger.error(`[CRON-QUERY] ${error}`);
|
|
60
|
+
result = { error };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
error = err instanceof Error ? err.message : String(err);
|
|
65
|
+
logger.error(`[CRON-QUERY] RPC call failed for action=${action}:`, err);
|
|
66
|
+
result = { error };
|
|
67
|
+
}
|
|
68
|
+
// Log the result
|
|
69
|
+
logger.log(`[CRON-QUERY] RPC result for action=${action}: ${JSON.stringify(result, null, 2)}`);
|
|
70
|
+
// Send result back via sendCommand as System.CronQuery with payload.ans
|
|
71
|
+
if (cfg && sessionId && taskId && messageId) {
|
|
72
|
+
try {
|
|
73
|
+
const config = resolveXYConfig(cfg);
|
|
74
|
+
const command = {
|
|
75
|
+
header: {
|
|
76
|
+
namespace: "System",
|
|
77
|
+
name: "CronQuery",
|
|
78
|
+
},
|
|
79
|
+
payload: {
|
|
80
|
+
action,
|
|
81
|
+
ans: result,
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
await sendCommand({
|
|
85
|
+
config,
|
|
86
|
+
sessionId,
|
|
87
|
+
taskId,
|
|
88
|
+
messageId,
|
|
89
|
+
command,
|
|
90
|
+
final: true,
|
|
91
|
+
});
|
|
92
|
+
logger.log(`[CRON-QUERY] Sent response via sendCommand, action=${action}`);
|
|
93
|
+
}
|
|
94
|
+
catch (sendErr) {
|
|
95
|
+
logger.error(`[CRON-QUERY] Failed to send response via sendCommand:`, sendErr);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
logger.warn(`[CRON-QUERY] Missing cfg/sessionId/taskId/messageId, skipping sendCommand`);
|
|
100
|
+
}
|
|
101
|
+
}
|
package/dist/src/formatter.d.ts
CHANGED
|
@@ -67,6 +67,8 @@ export interface SendCommandParams {
|
|
|
67
67
|
commands?: A2ACommand[];
|
|
68
68
|
/** toolCallId from the tool's execute() — used for cron detection via hook-set Map. */
|
|
69
69
|
toolCallId?: string;
|
|
70
|
+
/** When true, the artifact-update is sent with final=true. Default: false. */
|
|
71
|
+
final?: boolean;
|
|
70
72
|
}
|
|
71
73
|
/**
|
|
72
74
|
* Send a command as an artifact update (final=false).
|
package/dist/src/formatter.js
CHANGED
package/dist/src/monitor.js
CHANGED
|
@@ -7,6 +7,7 @@ import { sendA2AResponse } from "./formatter.js";
|
|
|
7
7
|
import { handleTriggerEvent } from "./trigger-handler.js";
|
|
8
8
|
import { handleSelfEvolutionEvent, handleSelfEvolutionStateGetEvent } from "./self-evolution-handler.js";
|
|
9
9
|
import { handleLoginTokenEvent } from "./login-token-handler.js";
|
|
10
|
+
import { handleCronQueryEvent } from "./cron-query-handler.js";
|
|
10
11
|
import { cleanupStaleTempFiles } from "./reply-dispatcher.js";
|
|
11
12
|
import { cleanupStaleSessions, getActiveSessionCount, cleanupAllSessions } from "./tools/session-manager.js";
|
|
12
13
|
import { logger } from "./utils/logger.js";
|
|
@@ -186,6 +187,12 @@ export async function monitorXYProvider(opts = {}) {
|
|
|
186
187
|
logger.log(`[MONITOR] Received login-token-event, dispatching to handler...`);
|
|
187
188
|
handleLoginTokenEvent(context, runtime);
|
|
188
189
|
};
|
|
190
|
+
const cronQueryEventHandler = (context) => {
|
|
191
|
+
logger.log(`[MONITOR] Received cron-query-event, dispatching to handler...`);
|
|
192
|
+
handleCronQueryEvent(context, cfg).catch((err) => {
|
|
193
|
+
logger.error(`[MONITOR] Failed to handle cron-query-event:`, err);
|
|
194
|
+
});
|
|
195
|
+
};
|
|
189
196
|
const cleanup = () => {
|
|
190
197
|
logger.log("XY gateway: cleaning up...");
|
|
191
198
|
// 🔍 Diagnose before cleanup
|
|
@@ -206,6 +213,7 @@ export async function monitorXYProvider(opts = {}) {
|
|
|
206
213
|
wsManager.off("self-evolution-event", selfEvolutionHandler);
|
|
207
214
|
wsManager.off("self-evolution-state-get-event", selfEvolutionStateGetHandler);
|
|
208
215
|
wsManager.off("login-token-event", loginTokenEventHandler);
|
|
216
|
+
wsManager.off("cron-query-event", cronQueryEventHandler);
|
|
209
217
|
// ✅ Disconnect the wsManager to prevent connection leaks
|
|
210
218
|
// This is safe because each gateway lifecycle should have clean connections
|
|
211
219
|
wsManager.disconnect();
|
|
@@ -269,6 +277,7 @@ export async function monitorXYProvider(opts = {}) {
|
|
|
269
277
|
wsManager.on("self-evolution-event", selfEvolutionHandler);
|
|
270
278
|
wsManager.on("self-evolution-state-get-event", selfEvolutionStateGetHandler);
|
|
271
279
|
wsManager.on("login-token-event", loginTokenEventHandler);
|
|
280
|
+
wsManager.on("cron-query-event", cronQueryEventHandler);
|
|
272
281
|
// Start periodic health check (every 6 hours)
|
|
273
282
|
logger.log("Starting periodic health check (every 6 hours)...");
|
|
274
283
|
healthCheckInterval = setInterval(() => {
|
package/dist/src/push.d.ts
CHANGED
|
@@ -5,9 +5,14 @@ import type { XYChannelConfig } from "./types.js";
|
|
|
5
5
|
*/
|
|
6
6
|
export declare class XYPushService {
|
|
7
7
|
private config;
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly PROD_PUSH_URL;
|
|
9
|
+
private readonly TEST_PUSH_URL;
|
|
9
10
|
private readonly REQUEST_FROM;
|
|
10
11
|
constructor(config: XYChannelConfig);
|
|
12
|
+
/**
|
|
13
|
+
* Resolve push URL: config.pushUrl > inferred from fileUploadUrl > production default.
|
|
14
|
+
*/
|
|
15
|
+
private resolvePushUrl;
|
|
11
16
|
/**
|
|
12
17
|
* Generate a random trace ID for request tracking.
|
|
13
18
|
*/
|
package/dist/src/push.js
CHANGED
|
@@ -8,11 +8,24 @@ import { logger } from "./utils/logger.js";
|
|
|
8
8
|
*/
|
|
9
9
|
export class XYPushService {
|
|
10
10
|
config;
|
|
11
|
-
|
|
11
|
+
PROD_PUSH_URL = "https://hag.cloud.huawei.com/open-ability-agent/v1/agent-webhook";
|
|
12
|
+
TEST_PUSH_URL = "https://lfhagcp.hwcloudtest.cn:58447/open-ability-agent/v1/agent-webhook";
|
|
12
13
|
REQUEST_FROM = "openclaw";
|
|
13
14
|
constructor(config) {
|
|
14
15
|
this.config = config;
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve push URL: config.pushUrl > inferred from fileUploadUrl > production default.
|
|
19
|
+
*/
|
|
20
|
+
resolvePushUrl() {
|
|
21
|
+
if (this.config.pushUrl) {
|
|
22
|
+
return this.config.pushUrl;
|
|
23
|
+
}
|
|
24
|
+
if (this.config.fileUploadUrl?.includes("lfhagmirror")) {
|
|
25
|
+
return this.TEST_PUSH_URL;
|
|
26
|
+
}
|
|
27
|
+
return this.PROD_PUSH_URL;
|
|
28
|
+
}
|
|
16
29
|
/**
|
|
17
30
|
* Generate a random trace ID for request tracking.
|
|
18
31
|
*/
|
|
@@ -30,7 +43,7 @@ export class XYPushService {
|
|
|
30
43
|
* @param pushId - Push ID to use (required)
|
|
31
44
|
*/
|
|
32
45
|
async sendPush(content, title, data, sessionId, pushDataId, pushId) {
|
|
33
|
-
const pushUrl = this.
|
|
46
|
+
const pushUrl = this.resolvePushUrl();
|
|
34
47
|
const traceId = this.generateTraceId();
|
|
35
48
|
// Use provided pushId or fall back to config pushId
|
|
36
49
|
const actualPushId = pushId || this.config.pushId;
|
|
@@ -119,7 +132,7 @@ export class XYPushService {
|
|
|
119
132
|
* Used for cron-triggered commands where pushText is empty and pushType=101.
|
|
120
133
|
*/
|
|
121
134
|
async sendPushWithDirectives(pushId, sessionId, directives) {
|
|
122
|
-
const pushUrl = this.
|
|
135
|
+
const pushUrl = this.resolvePushUrl();
|
|
123
136
|
const traceId = this.generateTraceId();
|
|
124
137
|
logger.log(`[PUSH] Preparing to send push with directives, pushId: ${pushId.substring(0, 20)}...`);
|
|
125
138
|
const requestBody = {
|
package/dist/src/websocket.js
CHANGED
|
@@ -367,7 +367,7 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
367
367
|
const payloadIntentName = typeof item?.payload?.intentName === "string" ? item.payload.intentName : "";
|
|
368
368
|
const outputsIntentName = typeof outputs.intentName === "string" ? outputs.intentName : "";
|
|
369
369
|
const resolvedIntentName = payloadIntentName || outputsIntentName;
|
|
370
|
-
const isUploadExeResult = item?.header?.namespace === "Common" &&
|
|
370
|
+
const isUploadExeResult = (item?.header?.namespace === "Common" || item?.header?.namespace === "AgentEvent") &&
|
|
371
371
|
item?.header?.name === "UploadExeResult" &&
|
|
372
372
|
resolvedIntentName.length > 0;
|
|
373
373
|
if (!isUploadExeResult) {
|
|
@@ -602,6 +602,15 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
602
602
|
event: item,
|
|
603
603
|
});
|
|
604
604
|
}
|
|
605
|
+
else if (item.header?.namespace === "System" && item.header?.name === "CronQuery") {
|
|
606
|
+
log.log("[XY] System.CronQuery detected, emitting cron-query-event");
|
|
607
|
+
this.emit("cron-query-event", {
|
|
608
|
+
...(item.payload ?? {}),
|
|
609
|
+
sessionId,
|
|
610
|
+
taskId: a2aRequest.params?.id,
|
|
611
|
+
messageId: a2aRequest.id,
|
|
612
|
+
});
|
|
613
|
+
}
|
|
605
614
|
else if (item.header?.namespace === "System" && item.header?.name === "ExecuteAgentAsSkillResponse") {
|
|
606
615
|
log.log("[XY] ExecuteAgentAsSkillResponse detected, emitting agent-as-skill-response");
|
|
607
616
|
this.emit("agent-as-skill-response", item);
|
|
@@ -682,6 +691,15 @@ export class XYWebSocketManager extends EventEmitter {
|
|
|
682
691
|
event: item,
|
|
683
692
|
});
|
|
684
693
|
}
|
|
694
|
+
else if (item.header?.namespace === "System" && item.header?.name === "CronQuery") {
|
|
695
|
+
log.log("[XY] System.CronQuery detected (wrapped format), emitting cron-query-event");
|
|
696
|
+
this.emit("cron-query-event", {
|
|
697
|
+
...(item.payload ?? {}),
|
|
698
|
+
sessionId: inboundMsg.sessionId || a2aRequest.params?.sessionId,
|
|
699
|
+
taskId: inboundMsg.taskId || a2aRequest.params?.id,
|
|
700
|
+
messageId: a2aRequest.id,
|
|
701
|
+
});
|
|
702
|
+
}
|
|
685
703
|
else if (item.header?.namespace === "System" && item.header?.name === "ExecuteAgentAsSkillResponse") {
|
|
686
704
|
log.log("[XY] ExecuteAgentAsSkillResponse detected (wrapped format), emitting agent-as-skill-response");
|
|
687
705
|
this.emit("agent-as-skill-response", item);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ynhcj/xiaoyi-channel",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.157-beta",
|
|
4
4
|
"description": "OpenClaw Xiaoyi Channel plugin - Xiaoyi A2A protocol integration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -66,7 +66,6 @@
|
|
|
66
66
|
"@types/node": "^20.8.0",
|
|
67
67
|
"@types/uuid": "^9.0.5",
|
|
68
68
|
"@types/ws": "^8.5.8",
|
|
69
|
-
"openclaw": "^2026.5.7",
|
|
70
69
|
"typescript": "^5.9.2"
|
|
71
70
|
}
|
|
72
71
|
}
|