palz-connector 1.6.9 → 1.7.1
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/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/palz-connector.config.json +4 -4
- package/src/activity.js +11 -15
- package/src/channel.js +13 -10
- package/src/monitor.js +8 -10
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"enabled": true,
|
|
3
|
-
"streamUrl": "ws://
|
|
4
|
-
"apiBaseUrl": "http://
|
|
3
|
+
"streamUrl": "ws://claw-server:8787/ws/bot",
|
|
4
|
+
"apiBaseUrl": "http://claw-server:8787/api",
|
|
5
5
|
"clawGatewayUrl": "http://claw-gateway:8080",
|
|
6
|
-
"activityReportEnabled":
|
|
6
|
+
"activityReportEnabled": true,
|
|
7
7
|
"sessionTimeout": 1800000,
|
|
8
8
|
"groupContextCache": false,
|
|
9
9
|
"showProcess": true,
|
|
10
|
-
"kbEngineUrl": "http://
|
|
10
|
+
"kbEngineUrl": "http://uniclaw-kb-engine:8070",
|
|
11
11
|
"controlPort": 8008
|
|
12
12
|
}
|
package/src/activity.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Palz IM
|
|
2
|
+
* Palz IM WebSocket 连接成功后的 claw-gateway 活动上报。
|
|
3
3
|
*/
|
|
4
4
|
const ACTIVITY_REPORT_TIMEOUT_MS = 2000;
|
|
5
5
|
const ACTIVITY_REPORT_PATH_PREFIX = "/openclaw-gateway/be/deployments";
|
|
6
6
|
const warnedMissingConfig = new Set();
|
|
7
|
+
const SERVICE_NAME = process.env.OPENCLAW_WORKSPACE_POOL_SERVICE_NAME ?? "";
|
|
7
8
|
function formatDateTimeWithOffset(date) {
|
|
8
9
|
const pad = (n, width = 2) => String(n).padStart(width, "0");
|
|
9
10
|
const offsetMinutes = -date.getTimezoneOffset();
|
|
@@ -23,7 +24,7 @@ function resolveActivityUrl(baseUrl, releaseName) {
|
|
|
23
24
|
return `${normalizedBase}${ACTIVITY_REPORT_PATH_PREFIX}/${encodeURIComponent(releaseName)}/activity`;
|
|
24
25
|
}
|
|
25
26
|
export async function reportPalzActivity(params) {
|
|
26
|
-
const { config,
|
|
27
|
+
const { config, connectedAt, runtime, accountId } = params;
|
|
27
28
|
const log = typeof runtime?.log === "function" ? runtime.log : console.log;
|
|
28
29
|
const error = typeof runtime?.error === "function" ? runtime.error : console.error;
|
|
29
30
|
const tag = `palz[${accountId ?? config.botId ?? "default"}]`;
|
|
@@ -41,22 +42,17 @@ export async function reportPalzActivity(params) {
|
|
|
41
42
|
}
|
|
42
43
|
const payload = {
|
|
43
44
|
source: "palz-connector",
|
|
44
|
-
eventType: "
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
userId: msg.owner_id ?? "",
|
|
49
|
-
senderId: msg.sender_id,
|
|
50
|
-
receivedAt: formatDateTimeWithOffset(receivedAt),
|
|
45
|
+
eventType: "ws_connected",
|
|
46
|
+
releaseName,
|
|
47
|
+
serviceName: SERVICE_NAME,
|
|
48
|
+
connectedAt: formatDateTimeWithOffset(connectedAt),
|
|
51
49
|
};
|
|
52
|
-
if (msg.traceparent) {
|
|
53
|
-
payload.traceId = msg.traceparent;
|
|
54
|
-
}
|
|
55
50
|
const url = resolveActivityUrl(baseUrl, releaseName);
|
|
56
51
|
const body = JSON.stringify(payload);
|
|
57
52
|
const controller = new AbortController();
|
|
58
53
|
const timeout = setTimeout(() => controller.abort(), ACTIVITY_REPORT_TIMEOUT_MS);
|
|
59
54
|
const startMs = Date.now();
|
|
55
|
+
log(`${tag}: [ACTIVITY_REPORT] reporting eventType=ws_connected url=${url} body=${body}`);
|
|
60
56
|
try {
|
|
61
57
|
const response = await fetch(url, {
|
|
62
58
|
method: "POST",
|
|
@@ -67,15 +63,15 @@ export async function reportPalzActivity(params) {
|
|
|
67
63
|
const elapsedMs = Date.now() - startMs;
|
|
68
64
|
const responseText = await response.text().catch(() => "");
|
|
69
65
|
if (!response.ok) {
|
|
70
|
-
error(`${tag}: [ACTIVITY_REPORT] failed status=${response.status} elapsed=${elapsedMs}ms
|
|
66
|
+
error(`${tag}: [ACTIVITY_REPORT] failed status=${response.status} elapsed=${elapsedMs}ms response=${responseText.slice(0, 300)}`);
|
|
71
67
|
return;
|
|
72
68
|
}
|
|
73
|
-
log(`${tag}: [ACTIVITY_REPORT] ok status=${response.status} elapsed=${elapsedMs}ms
|
|
69
|
+
log(`${tag}: [ACTIVITY_REPORT] ok status=${response.status} elapsed=${elapsedMs}ms eventType=ws_connected`);
|
|
74
70
|
}
|
|
75
71
|
catch (err) {
|
|
76
72
|
const elapsedMs = Date.now() - startMs;
|
|
77
73
|
const reason = err?.name === "AbortError" ? `timeout ${ACTIVITY_REPORT_TIMEOUT_MS}ms` : (err?.message ?? String(err));
|
|
78
|
-
error(`${tag}: [ACTIVITY_REPORT] error elapsed=${elapsedMs}ms
|
|
74
|
+
error(`${tag}: [ACTIVITY_REPORT] error elapsed=${elapsedMs}ms reason=${reason}`);
|
|
79
75
|
}
|
|
80
76
|
finally {
|
|
81
77
|
clearTimeout(timeout);
|
package/src/channel.js
CHANGED
|
@@ -72,11 +72,10 @@ export const palzPlugin = {
|
|
|
72
72
|
gateway: {
|
|
73
73
|
startAccount: async (ctx) => {
|
|
74
74
|
const log = typeof ctx.runtime?.log === "function" ? ctx.runtime.log : console.log;
|
|
75
|
-
const logInfo = typeof ctx.log?.info === "function" ? ctx.log.info.bind(ctx.log) : log;
|
|
76
75
|
const error = typeof ctx.runtime?.error === "function" ? ctx.runtime.error : console.error;
|
|
77
|
-
|
|
76
|
+
log("palz-gateway: [startAccount] 输入: accountId=" + JSON.stringify(ctx.accountId));
|
|
78
77
|
if (ctx.accountId !== PALZ_MANAGER_ACCOUNT_ID) {
|
|
79
|
-
|
|
78
|
+
log("palz-gateway: [startAccount] non-manager account " + JSON.stringify(ctx.accountId) + ", returning abort-pending promise");
|
|
80
79
|
return new Promise((resolve) => {
|
|
81
80
|
if (ctx.abortSignal?.aborted) {
|
|
82
81
|
resolve();
|
|
@@ -88,15 +87,17 @@ export const palzPlugin = {
|
|
|
88
87
|
const baseConfig = resolvePalzConfig(ctx.cfg);
|
|
89
88
|
if (!baseConfig.streamUrl || !baseConfig.apiBaseUrl) {
|
|
90
89
|
const errMsg = "Palz manager not configured (missing streamUrl/apiBaseUrl)";
|
|
91
|
-
|
|
90
|
+
log("palz-gateway: [startAccount] 失败: " + errMsg);
|
|
92
91
|
throw new Error(errMsg);
|
|
93
92
|
}
|
|
94
|
-
|
|
93
|
+
log("palz-gateway: [startAccount] 启动 manager, streamUrl=" + baseConfig.streamUrl);
|
|
95
94
|
const manager = new ConnectionManager({
|
|
96
95
|
cfg: ctx.cfg,
|
|
97
96
|
baseConfig,
|
|
98
97
|
runtime: ctx.runtime,
|
|
99
|
-
log
|
|
98
|
+
// 用 runtime.log(写文件),而非仅 stdout 的 ctx.log.info,
|
|
99
|
+
// 使连接生命周期日志(reconcile/add/remove/shutdown)落入 palz-*.log。
|
|
100
|
+
log,
|
|
100
101
|
error,
|
|
101
102
|
});
|
|
102
103
|
const scanner = startUserDirScanner({
|
|
@@ -105,7 +106,7 @@ export const palzPlugin = {
|
|
|
105
106
|
error("palz-gateway: reconcile error: " + String(err));
|
|
106
107
|
});
|
|
107
108
|
},
|
|
108
|
-
log
|
|
109
|
+
log,
|
|
109
110
|
error,
|
|
110
111
|
});
|
|
111
112
|
// Stop service: disconnect all WS connections and prevent scanner-triggered reconnects.
|
|
@@ -115,7 +116,7 @@ export const palzPlugin = {
|
|
|
115
116
|
if (stopped)
|
|
116
117
|
return;
|
|
117
118
|
stopped = true;
|
|
118
|
-
|
|
119
|
+
log("palz-gateway: [doStop] stopping service, shutting down scanner + manager");
|
|
119
120
|
scanner.stop();
|
|
120
121
|
manager.shutdown();
|
|
121
122
|
};
|
|
@@ -133,13 +134,15 @@ export const palzPlugin = {
|
|
|
133
134
|
},
|
|
134
135
|
cfg: ctx.cfg,
|
|
135
136
|
runtime: ctx.runtime,
|
|
136
|
-
log
|
|
137
|
+
// 用 runtime.log(写入 palz-*.log 文件),而非 ctx.log.info(仅 stdout),
|
|
138
|
+
// 使 control-server 的回调日志与消息链路日志落到同一文件,便于排查。
|
|
139
|
+
log,
|
|
137
140
|
error,
|
|
138
141
|
});
|
|
139
142
|
}
|
|
140
143
|
return new Promise((resolve) => {
|
|
141
144
|
const onAbort = () => {
|
|
142
|
-
|
|
145
|
+
log("palz-gateway: [startAccount] abort received, shutting down manager");
|
|
143
146
|
controlServer?.close();
|
|
144
147
|
doStop();
|
|
145
148
|
resolve();
|
package/src/monitor.js
CHANGED
|
@@ -167,6 +167,14 @@ export async function monitorPalzProvider(params) {
|
|
|
167
167
|
lastPongAt = connectedAt;
|
|
168
168
|
consecutive4002 = 0;
|
|
169
169
|
log(`palz[${accountId}]: WebSocket connected, bot_id=${config.botId}`);
|
|
170
|
+
reportPalzActivity({
|
|
171
|
+
config,
|
|
172
|
+
connectedAt: new Date(connectedAt),
|
|
173
|
+
runtime,
|
|
174
|
+
accountId,
|
|
175
|
+
}).catch((err) => {
|
|
176
|
+
error(`palz[${accountId}]: [ACTIVITY_REPORT] unhandled error: ${err.message ?? err}`);
|
|
177
|
+
});
|
|
170
178
|
pingInterval = setInterval(() => {
|
|
171
179
|
if (ws.readyState === WebSocket.OPEN) {
|
|
172
180
|
const timeSinceLastPong = Date.now() - lastPongAt;
|
|
@@ -195,7 +203,6 @@ export async function monitorPalzProvider(params) {
|
|
|
195
203
|
}
|
|
196
204
|
});
|
|
197
205
|
ws.on("message", (data) => {
|
|
198
|
-
const receivedAt = new Date();
|
|
199
206
|
const raw = data.toString();
|
|
200
207
|
try {
|
|
201
208
|
const msg = JSON.parse(raw);
|
|
@@ -209,15 +216,6 @@ export async function monitorPalzProvider(params) {
|
|
|
209
216
|
try {
|
|
210
217
|
span.setAttribute("raw_message", raw);
|
|
211
218
|
log(`palz[${accountId}]: [WS_RECV] #${messageCount} full_message=${raw} traceId=${span.spanContext().traceId}`);
|
|
212
|
-
reportPalzActivity({
|
|
213
|
-
config,
|
|
214
|
-
msg,
|
|
215
|
-
receivedAt,
|
|
216
|
-
runtime,
|
|
217
|
-
accountId,
|
|
218
|
-
}).catch((err) => {
|
|
219
|
-
error(`palz[${accountId}]: [ACTIVITY_REPORT] unhandled error: ${err.message ?? err}`);
|
|
220
|
-
});
|
|
221
219
|
// agent_id:从消息中取,缺失/空时默认为 {userId}-main
|
|
222
220
|
let messageAgentId = typeof msg.agent_id === "string" ? msg.agent_id.trim() : "";
|
|
223
221
|
if (!messageAgentId) {
|