palz-connector 1.4.7 → 1.4.9
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 +2 -0
- package/palz-connector.dev.config.json +2 -0
- package/palz-connector.prod.config.json +2 -0
- package/palz-connector.staging.config.json +2 -0
- package/src/activity.ts +102 -0
- package/src/bot.ts +4 -1
- package/src/channel.ts +2 -0
- package/src/config.ts +3 -1
- package/src/monitor.ts +87 -58
- package/src/types.ts +6 -0
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
"enabled": true,
|
|
3
3
|
"streamUrl": "ws://14.103.148.99:8090/ws/bot",
|
|
4
4
|
"apiBaseUrl": "http://14.103.148.99:8090/api",
|
|
5
|
+
"clawGatewayUrl": "http://claw-gateway:8080",
|
|
6
|
+
"activityReportEnabled": false,
|
|
5
7
|
"sessionTimeout": 1800000,
|
|
6
8
|
"groupContextCache": false,
|
|
7
9
|
"showProcess": true
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
"enabled": true,
|
|
3
3
|
"streamUrl": "wss://claw-server.csaiagent.com/ws/bot",
|
|
4
4
|
"apiBaseUrl": "https://claw-server.csaiagent.com/api",
|
|
5
|
+
"clawGatewayUrl": "http://claw-gateway:8080",
|
|
6
|
+
"activityReportEnabled": true,
|
|
5
7
|
"sessionTimeout": 1800000,
|
|
6
8
|
"groupContextCache": false,
|
|
7
9
|
"showProcess": true
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
"enabled": true,
|
|
3
3
|
"streamUrl": "wss://claw-server.csagentai.com/ws/bot",
|
|
4
4
|
"apiBaseUrl": "https://claw-server.csagentai.com/api",
|
|
5
|
+
"clawGatewayUrl": "http://claw-gateway:8080",
|
|
6
|
+
"activityReportEnabled": true,
|
|
5
7
|
"sessionTimeout": 1800000,
|
|
6
8
|
"groupContextCache": false,
|
|
7
9
|
"showProcess": true
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
"enabled": true,
|
|
3
3
|
"streamUrl": "wss://claw-server.csjkagent.com/ws/bot",
|
|
4
4
|
"apiBaseUrl": "https://claw-server.csjkagent.com/api",
|
|
5
|
+
"clawGatewayUrl": "https://claw-server.csjkagent.com/api",
|
|
6
|
+
"activityReportEnabled": true,
|
|
5
7
|
"sessionTimeout": 1800000,
|
|
6
8
|
"groupContextCache": false,
|
|
7
9
|
"showProcess": true
|
package/src/activity.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Palz IM 收到消息后的 claw-gateway 活动上报。
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { PalzConfig, PalzMessageEvent } from "./types.js";
|
|
6
|
+
|
|
7
|
+
const ACTIVITY_REPORT_TIMEOUT_MS = 2000;
|
|
8
|
+
const ACTIVITY_REPORT_PATH_PREFIX = "/openclaw-gateway/be/deployments";
|
|
9
|
+
|
|
10
|
+
const warnedMissingConfig = new Set<string>();
|
|
11
|
+
|
|
12
|
+
export interface ReportPalzActivityParams {
|
|
13
|
+
config: PalzConfig;
|
|
14
|
+
msg: PalzMessageEvent;
|
|
15
|
+
receivedAt: Date;
|
|
16
|
+
runtime?: any;
|
|
17
|
+
accountId?: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function formatDateTimeWithOffset(date: Date): string {
|
|
21
|
+
const pad = (n: number, width = 2) => String(n).padStart(width, "0");
|
|
22
|
+
const offsetMinutes = -date.getTimezoneOffset();
|
|
23
|
+
const sign = offsetMinutes >= 0 ? "+" : "-";
|
|
24
|
+
const absOffset = Math.abs(offsetMinutes);
|
|
25
|
+
const offsetHours = Math.floor(absOffset / 60);
|
|
26
|
+
const offsetRestMinutes = absOffset % 60;
|
|
27
|
+
|
|
28
|
+
return [
|
|
29
|
+
`${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`,
|
|
30
|
+
"T",
|
|
31
|
+
`${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`,
|
|
32
|
+
`${sign}${pad(offsetHours)}:${pad(offsetRestMinutes)}`,
|
|
33
|
+
].join("");
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function resolveActivityUrl(baseUrl: string, releaseName: string): string {
|
|
37
|
+
const normalizedBase = baseUrl.replace(/\/+$/, "");
|
|
38
|
+
return `${normalizedBase}${ACTIVITY_REPORT_PATH_PREFIX}/${encodeURIComponent(releaseName)}/activity`;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function reportPalzActivity(params: ReportPalzActivityParams): Promise<void> {
|
|
42
|
+
const { config, msg, receivedAt, runtime, accountId } = params;
|
|
43
|
+
const log = typeof runtime?.log === "function" ? runtime.log : console.log;
|
|
44
|
+
const error = typeof runtime?.error === "function" ? runtime.error : console.error;
|
|
45
|
+
const tag = `palz[${accountId ?? config.botId ?? "default"}]`;
|
|
46
|
+
|
|
47
|
+
if (config.activityReportEnabled !== true) return;
|
|
48
|
+
|
|
49
|
+
const baseUrl = config.clawGatewayUrl?.trim();
|
|
50
|
+
const releaseName = (process.env.botID || config.botId || "").trim();
|
|
51
|
+
if (!baseUrl || !releaseName) {
|
|
52
|
+
const warnKey = `${accountId ?? ""}:${baseUrl ? "hasBaseUrl" : "missingBaseUrl"}:${releaseName ? "hasRelease" : "missingRelease"}`;
|
|
53
|
+
if (!warnedMissingConfig.has(warnKey)) {
|
|
54
|
+
warnedMissingConfig.add(warnKey);
|
|
55
|
+
error(`${tag}: [ACTIVITY_REPORT] enabled but missing ${!baseUrl ? "clawGatewayUrl" : "botID/releaseName"}, skip`);
|
|
56
|
+
}
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const payload: Record<string, unknown> = {
|
|
61
|
+
source: "palz-connector",
|
|
62
|
+
eventType: "im_message_received",
|
|
63
|
+
messageId: msg.msg_id,
|
|
64
|
+
conversationId: msg.conversation_id,
|
|
65
|
+
conversationType: msg.conversation_type || "direct",
|
|
66
|
+
userId: msg.owner_id ?? "",
|
|
67
|
+
senderId: msg.sender_id,
|
|
68
|
+
receivedAt: formatDateTimeWithOffset(receivedAt),
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
if (msg.traceparent) {
|
|
72
|
+
payload.traceId = msg.traceparent;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const url = resolveActivityUrl(baseUrl, releaseName);
|
|
76
|
+
const body = JSON.stringify(payload);
|
|
77
|
+
const controller = new AbortController();
|
|
78
|
+
const timeout = setTimeout(() => controller.abort(), ACTIVITY_REPORT_TIMEOUT_MS);
|
|
79
|
+
const startMs = Date.now();
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const response = await fetch(url, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: { "Content-Type": "application/json" },
|
|
85
|
+
body,
|
|
86
|
+
signal: controller.signal,
|
|
87
|
+
});
|
|
88
|
+
const elapsedMs = Date.now() - startMs;
|
|
89
|
+
const responseText = await response.text().catch(() => "");
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
error(`${tag}: [ACTIVITY_REPORT] failed status=${response.status} elapsed=${elapsedMs}ms msg_id=${msg.msg_id} response=${responseText.slice(0, 300)}`);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
log(`${tag}: [ACTIVITY_REPORT] ok status=${response.status} elapsed=${elapsedMs}ms msg_id=${msg.msg_id}`);
|
|
95
|
+
} catch (err: any) {
|
|
96
|
+
const elapsedMs = Date.now() - startMs;
|
|
97
|
+
const reason = err?.name === "AbortError" ? `timeout ${ACTIVITY_REPORT_TIMEOUT_MS}ms` : (err?.message ?? String(err));
|
|
98
|
+
error(`${tag}: [ACTIVITY_REPORT] error elapsed=${elapsedMs}ms msg_id=${msg.msg_id} reason=${reason}`);
|
|
99
|
+
} finally {
|
|
100
|
+
clearTimeout(timeout);
|
|
101
|
+
}
|
|
102
|
+
}
|
package/src/bot.ts
CHANGED
|
@@ -558,6 +558,9 @@ async function _dispatchPalzMessageInner(params: HandlePalzMessageParams): Promi
|
|
|
558
558
|
if (groupId) {
|
|
559
559
|
untrustedContext.push(`group_id: ${groupId}`);
|
|
560
560
|
}
|
|
561
|
+
if (msg.group_name) {
|
|
562
|
+
untrustedContext.push(`group_name: ${msg.group_name}`);
|
|
563
|
+
}
|
|
561
564
|
if (msg.group_owner_id) {
|
|
562
565
|
untrustedContext.push(`group_owner_id: ${msg.group_owner_id}`);
|
|
563
566
|
}
|
|
@@ -584,7 +587,7 @@ async function _dispatchPalzMessageInner(params: HandlePalzMessageParams): Promi
|
|
|
584
587
|
SessionKey: route.sessionKey,
|
|
585
588
|
AccountId: route.accountId,
|
|
586
589
|
ChatType: chatType,
|
|
587
|
-
GroupSubject: isGroup ? msg.conversation_id : undefined,
|
|
590
|
+
GroupSubject: isGroup ? (msg.group_name || msg.conversation_id) : undefined,
|
|
588
591
|
SenderId: msg.sender_id,
|
|
589
592
|
SenderName: senderName,
|
|
590
593
|
UntrustedContext: untrustedContext,
|
package/src/channel.ts
CHANGED
|
@@ -44,6 +44,8 @@ export const palzPlugin = {
|
|
|
44
44
|
enabled: { type: "boolean" },
|
|
45
45
|
streamUrl: { type: "string" },
|
|
46
46
|
apiBaseUrl: { type: "string" },
|
|
47
|
+
clawGatewayUrl: { type: "string" },
|
|
48
|
+
activityReportEnabled: { type: "boolean" },
|
|
47
49
|
sessionTimeout: { type: "integer", minimum: 0 },
|
|
48
50
|
},
|
|
49
51
|
},
|
package/src/config.ts
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 配置来源:
|
|
5
5
|
* - botId: 仅从环境变量 botID 读取
|
|
6
|
-
* - streamUrl / apiBaseUrl / sessionTimeout: 从配置文件读取
|
|
6
|
+
* - streamUrl / apiBaseUrl / clawGatewayUrl / sessionTimeout: 从配置文件读取
|
|
7
7
|
* - 若环境变量 HELM_ENV 存在且非空,读取 palz-connector.{HELM_ENV}.config.json
|
|
8
8
|
* - 否则读取默认配置文件 palz-connector.config.json
|
|
9
9
|
*/
|
|
@@ -71,6 +71,8 @@ export function resolvePalzConfig(_cfg?: any): PalzConfig {
|
|
|
71
71
|
botId: process.env.botID || "",
|
|
72
72
|
streamUrl: file.streamUrl || "",
|
|
73
73
|
apiBaseUrl: file.apiBaseUrl || "",
|
|
74
|
+
clawGatewayUrl: file.clawGatewayUrl || "",
|
|
75
|
+
activityReportEnabled: file.activityReportEnabled === true,
|
|
74
76
|
sessionTimeout: file.sessionTimeout ?? DEFAULT_SESSION_TIMEOUT,
|
|
75
77
|
groupContextCache: file.groupContextCache !== false,
|
|
76
78
|
showProcess: file.showProcess === true,
|
package/src/monitor.ts
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import WebSocket from "ws";
|
|
9
9
|
import { handlePalzMessage } from "./bot.js";
|
|
10
|
+
import { reportPalzActivity } from "./activity.js";
|
|
10
11
|
import { tracer, extractTraceparentContext, SpanStatusCode } from "./tracing.js";
|
|
11
12
|
import type { PalzConfig, PalzMessageEvent } from "./types.js";
|
|
12
13
|
|
|
@@ -40,6 +41,7 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
40
41
|
let currentWs: WebSocket | null = null;
|
|
41
42
|
let consecutive4002 = 0;
|
|
42
43
|
const MAX_CONSECUTIVE_4002 = 10;
|
|
44
|
+
const MAX_RECONNECT_DELAY_MS = 16_000;
|
|
43
45
|
|
|
44
46
|
const cleanup = () => {
|
|
45
47
|
closed = true;
|
|
@@ -72,15 +74,28 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
72
74
|
}
|
|
73
75
|
abortSignal?.addEventListener("abort", handleAbort, { once: true });
|
|
74
76
|
|
|
75
|
-
function scheduleReconnect() {
|
|
77
|
+
function scheduleReconnect(delay = reconnectDelay, advanceBackoff = true) {
|
|
76
78
|
if (closed) return;
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
79
|
+
if (reconnectTimer) {
|
|
80
|
+
clearTimeout(reconnectTimer);
|
|
81
|
+
reconnectTimer = null;
|
|
82
|
+
}
|
|
83
|
+
log(`palz[${accountId}]: scheduling reconnect in ${delay}ms`);
|
|
84
|
+
reconnectTimer = setTimeout(() => {
|
|
85
|
+
reconnectTimer = null;
|
|
86
|
+
connect();
|
|
87
|
+
}, delay);
|
|
88
|
+
if (advanceBackoff) {
|
|
89
|
+
reconnectDelay = Math.min(reconnectDelay * 2, MAX_RECONNECT_DELAY_MS);
|
|
90
|
+
}
|
|
80
91
|
}
|
|
81
92
|
|
|
82
93
|
function connect() {
|
|
83
94
|
if (closed) return;
|
|
95
|
+
if (reconnectTimer) {
|
|
96
|
+
clearTimeout(reconnectTimer);
|
|
97
|
+
reconnectTimer = null;
|
|
98
|
+
}
|
|
84
99
|
|
|
85
100
|
let ws: WebSocket;
|
|
86
101
|
try {
|
|
@@ -94,7 +109,55 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
94
109
|
let connectedAt = 0;
|
|
95
110
|
let pingInterval: ReturnType<typeof setInterval> | null = null;
|
|
96
111
|
let messageCount = 0;
|
|
97
|
-
let
|
|
112
|
+
let ended = false;
|
|
113
|
+
|
|
114
|
+
const handleSocketEnd = (code: number, reasonStr: string) => {
|
|
115
|
+
if (ended) return;
|
|
116
|
+
ended = true;
|
|
117
|
+
if (pingInterval) {
|
|
118
|
+
clearInterval(pingInterval);
|
|
119
|
+
pingInterval = null;
|
|
120
|
+
}
|
|
121
|
+
if (closed) return;
|
|
122
|
+
|
|
123
|
+
const wasConnected = connectedAt > 0;
|
|
124
|
+
const stableMs = wasConnected ? Date.now() - connectedAt : 0;
|
|
125
|
+
|
|
126
|
+
// 4002: 被新连接替代,带退避重试
|
|
127
|
+
if (code === 4002) {
|
|
128
|
+
consecutive4002++;
|
|
129
|
+
if (consecutive4002 >= MAX_CONSECUTIVE_4002) {
|
|
130
|
+
log(
|
|
131
|
+
`palz[${accountId}]: replaced ${consecutive4002} times (code=4002), giving up`,
|
|
132
|
+
);
|
|
133
|
+
cleanup();
|
|
134
|
+
resolve();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const jitter = Math.floor(Math.random() * 2000);
|
|
138
|
+
const delay = 3000 * consecutive4002 + jitter;
|
|
139
|
+
log(
|
|
140
|
+
`palz[${accountId}]: replaced (code=4002, attempt=${consecutive4002}), retry in ${delay}ms`,
|
|
141
|
+
);
|
|
142
|
+
scheduleReconnect(delay, false);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 4001: bot_id 缺失,不重连
|
|
147
|
+
if (code === 4001) {
|
|
148
|
+
error(`palz[${accountId}]: bot_id missing (code=4001), not reconnecting`);
|
|
149
|
+
cleanup();
|
|
150
|
+
resolve();
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// 其他断开:指数退避重连
|
|
155
|
+
if (wasConnected && stableMs > 10_000) reconnectDelay = 1000;
|
|
156
|
+
log(
|
|
157
|
+
`palz[${accountId}]: disconnected (code=${code}, reason=${reasonStr}, uptime=${Math.round(stableMs / 1000)}s, msgs=${messageCount}), reconnecting in ${reconnectDelay}ms`,
|
|
158
|
+
);
|
|
159
|
+
scheduleReconnect();
|
|
160
|
+
};
|
|
98
161
|
|
|
99
162
|
ws.on("open", () => {
|
|
100
163
|
connectedAt = Date.now();
|
|
@@ -111,6 +174,7 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
111
174
|
});
|
|
112
175
|
|
|
113
176
|
ws.on("message", (data: Buffer) => {
|
|
177
|
+
const receivedAt = new Date();
|
|
114
178
|
const raw = data.toString();
|
|
115
179
|
try {
|
|
116
180
|
const msg = JSON.parse(raw) as PalzMessageEvent;
|
|
@@ -129,7 +193,22 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
129
193
|
|
|
130
194
|
log(`palz[${accountId}]: [WS_RECV] #${messageCount} full_message=${raw.slice(0, 1000)} traceId=${span.spanContext().traceId}`);
|
|
131
195
|
|
|
132
|
-
|
|
196
|
+
reportPalzActivity({
|
|
197
|
+
config,
|
|
198
|
+
msg,
|
|
199
|
+
receivedAt,
|
|
200
|
+
runtime,
|
|
201
|
+
accountId,
|
|
202
|
+
}).catch((err: any) => {
|
|
203
|
+
error(`palz[${accountId}]: [ACTIVITY_REPORT] unhandled error: ${err.message ?? err}`);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
handlePalzMessage({
|
|
207
|
+
cfg,
|
|
208
|
+
msg,
|
|
209
|
+
runtime,
|
|
210
|
+
accountId,
|
|
211
|
+
}).catch((err: any) => {
|
|
133
212
|
error(`palz[${accountId}]: [WS_RECV] handlePalzMessage unhandled error: ${err.message ?? err}`);
|
|
134
213
|
});
|
|
135
214
|
} catch (e) {
|
|
@@ -145,62 +224,12 @@ export async function monitorPalzProvider(params: MonitorPalzParams): Promise<vo
|
|
|
145
224
|
});
|
|
146
225
|
|
|
147
226
|
ws.on("close", (code: number, reason: Buffer) => {
|
|
148
|
-
|
|
149
|
-
if (pingInterval) {
|
|
150
|
-
clearInterval(pingInterval);
|
|
151
|
-
pingInterval = null;
|
|
152
|
-
}
|
|
153
|
-
if (closed) return;
|
|
154
|
-
|
|
155
|
-
const stableMs = Date.now() - connectedAt;
|
|
156
|
-
const reasonStr = reason?.toString() || "";
|
|
157
|
-
|
|
158
|
-
// 4002: 被新连接替代,带退避重试
|
|
159
|
-
if (code === 4002) {
|
|
160
|
-
consecutive4002++;
|
|
161
|
-
if (consecutive4002 >= MAX_CONSECUTIVE_4002) {
|
|
162
|
-
log(
|
|
163
|
-
`palz[${accountId}]: replaced ${consecutive4002} times (code=4002), giving up`,
|
|
164
|
-
);
|
|
165
|
-
cleanup();
|
|
166
|
-
resolve();
|
|
167
|
-
return;
|
|
168
|
-
}
|
|
169
|
-
const jitter = Math.floor(Math.random() * 2000);
|
|
170
|
-
const delay = 3000 * consecutive4002 + jitter;
|
|
171
|
-
log(
|
|
172
|
-
`palz[${accountId}]: replaced (code=4002, attempt=${consecutive4002}), retry in ${delay}ms`,
|
|
173
|
-
);
|
|
174
|
-
reconnectTimer = setTimeout(connect, delay);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// 4001: bot_id 缺失,不重连
|
|
179
|
-
if (code === 4001) {
|
|
180
|
-
error(`palz[${accountId}]: bot_id missing (code=4001), not reconnecting`);
|
|
181
|
-
cleanup();
|
|
182
|
-
resolve();
|
|
183
|
-
return;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
// 其他断开:指数退避重连
|
|
187
|
-
if (stableMs > 10_000) reconnectDelay = 1000;
|
|
188
|
-
log(
|
|
189
|
-
`palz[${accountId}]: disconnected (code=${code}, reason=${reasonStr}, uptime=${Math.round(stableMs / 1000)}s, msgs=${messageCount}), reconnecting in ${reconnectDelay}ms`,
|
|
190
|
-
);
|
|
191
|
-
scheduleReconnect();
|
|
227
|
+
handleSocketEnd(code, reason?.toString() || "");
|
|
192
228
|
});
|
|
193
229
|
|
|
194
230
|
ws.on("error", (err) => {
|
|
195
231
|
error(`palz[${accountId}]: WebSocket error: ${err.message}`);
|
|
196
|
-
|
|
197
|
-
closeFired = true;
|
|
198
|
-
if (pingInterval) {
|
|
199
|
-
clearInterval(pingInterval);
|
|
200
|
-
pingInterval = null;
|
|
201
|
-
}
|
|
202
|
-
scheduleReconnect();
|
|
203
|
-
}
|
|
232
|
+
handleSocketEnd(1006, err.message);
|
|
204
233
|
});
|
|
205
234
|
}
|
|
206
235
|
|
package/src/types.ts
CHANGED
|
@@ -39,6 +39,8 @@ export interface PalzMessageEvent {
|
|
|
39
39
|
group_id?: string;
|
|
40
40
|
/** 群主用户 ID,群聊时由 IM 下发 */
|
|
41
41
|
group_owner_id?: string;
|
|
42
|
+
/** 群聊名称,群聊时由 IM 下发 */
|
|
43
|
+
group_name?: string;
|
|
42
44
|
/** Lobster ID,标识 agent 身份(IM 通过此字段区分不同 agent) */
|
|
43
45
|
lobster_id?: string;
|
|
44
46
|
/** 群组类型,由 IM 下发 */
|
|
@@ -62,6 +64,10 @@ export interface PalzConfig {
|
|
|
62
64
|
botId?: string;
|
|
63
65
|
streamUrl?: string;
|
|
64
66
|
apiBaseUrl?: string;
|
|
67
|
+
/** claw-gateway 服务基础地址,例如 https://example.com */
|
|
68
|
+
clawGatewayUrl?: string;
|
|
69
|
+
/** 是否向 claw-gateway 上报 IM 消息接收事件,默认 false */
|
|
70
|
+
activityReportEnabled?: boolean;
|
|
65
71
|
sessionTimeout?: number;
|
|
66
72
|
/** 群聊上下文缓存开关:true=未@消息缓存为上下文(默认),false=所有群聊消息直接发送给AI */
|
|
67
73
|
groupContextCache?: boolean;
|