palz-connector 1.7.2 → 1.7.4-beta.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/palz-connector.global.dev.config.json +3 -2
- package/palz-connector.global.prod.config.json +3 -2
- package/palz-connector.global.staging.config.json +3 -2
- package/src/channel.js +1 -0
- package/src/config.js +3 -0
- package/src/gateway-relay.js +11 -6
- package/src/reply-dispatcher.js +3 -2
- package/src/tool-display.js +39 -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
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"enabled": true,
|
|
3
|
-
"streamUrl": "ws://claw-server:8787/ws/bot",
|
|
4
|
-
"apiBaseUrl": "http://claw-server:8787/api",
|
|
3
|
+
"streamUrl": "ws://claw-server:8787/im-server/ws/bot",
|
|
4
|
+
"apiBaseUrl": "http://claw-server:8787/im-server/api",
|
|
5
5
|
"clawGatewayUrl": "http://claw-gateway:8080",
|
|
6
6
|
"activityReportEnabled": true,
|
|
7
7
|
"sessionTimeout": 1800000,
|
|
8
8
|
"groupContextCache": false,
|
|
9
9
|
"showProcess": true,
|
|
10
|
+
"processLanguage": "en",
|
|
10
11
|
"kbEngineUrl": "http://uniclaw-kb-engine:8070",
|
|
11
12
|
"controlPort": 8008
|
|
12
13
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"enabled": true,
|
|
3
|
-
"streamUrl": "ws://claw-server:8787/ws/bot",
|
|
4
|
-
"apiBaseUrl": "http://claw-server:8787/api",
|
|
3
|
+
"streamUrl": "ws://claw-server:8787/im-server/ws/bot",
|
|
4
|
+
"apiBaseUrl": "http://claw-server:8787/im-server/api",
|
|
5
5
|
"clawGatewayUrl": "http://claw-gateway:8080",
|
|
6
6
|
"activityReportEnabled": true,
|
|
7
7
|
"sessionTimeout": 1800000,
|
|
8
8
|
"groupContextCache": false,
|
|
9
9
|
"showProcess": true,
|
|
10
|
+
"processLanguage": "en",
|
|
10
11
|
"kbEngineUrl": "http://uniclaw-kb-engine:8070",
|
|
11
12
|
"controlPort": 8008
|
|
12
13
|
}
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"enabled": true,
|
|
3
|
-
"streamUrl": "ws://claw-server:8787/ws/bot",
|
|
4
|
-
"apiBaseUrl": "http://claw-server:8787/api",
|
|
3
|
+
"streamUrl": "ws://claw-server:8787/im-server/ws/bot",
|
|
4
|
+
"apiBaseUrl": "http://claw-server:8787/im-server/api",
|
|
5
5
|
"clawGatewayUrl": "http://claw-gateway:8080",
|
|
6
6
|
"activityReportEnabled": true,
|
|
7
7
|
"sessionTimeout": 1800000,
|
|
8
8
|
"groupContextCache": false,
|
|
9
9
|
"showProcess": true,
|
|
10
|
+
"processLanguage": "en",
|
|
10
11
|
"kbEngineUrl": "http://uniclaw-kb-engine:8070",
|
|
11
12
|
"controlPort": 8008
|
|
12
13
|
}
|
package/src/channel.js
CHANGED
|
@@ -40,6 +40,7 @@ export const palzPlugin = {
|
|
|
40
40
|
clawGatewayUrl: { type: "string" },
|
|
41
41
|
activityReportEnabled: { type: "boolean" },
|
|
42
42
|
sessionTimeout: { type: "integer", minimum: 0 },
|
|
43
|
+
processLanguage: { type: "string", enum: ["zh", "en"] },
|
|
43
44
|
controlPort: { type: "integer", minimum: 0 },
|
|
44
45
|
},
|
|
45
46
|
},
|
package/src/config.js
CHANGED
|
@@ -15,6 +15,7 @@ const __dirname = path.dirname(__filename);
|
|
|
15
15
|
export const PALZ_MANAGER_ACCOUNT_ID = "palz-manager";
|
|
16
16
|
const DEFAULT_SESSION_TIMEOUT = 30 * 60 * 1000;
|
|
17
17
|
const DEFAULT_CONFIG_FILENAME = "palz-connector.config.json";
|
|
18
|
+
const DEFAULT_PROCESS_LANGUAGE = "zh";
|
|
18
19
|
let _cachedFileConfig = null;
|
|
19
20
|
let _configLoggedOnce = false;
|
|
20
21
|
let _configAdapterLoggedOnce = false;
|
|
@@ -57,6 +58,7 @@ function loadConfigFile() {
|
|
|
57
58
|
}
|
|
58
59
|
export function resolvePalzConfig(_cfg, botId) {
|
|
59
60
|
const file = loadConfigFile();
|
|
61
|
+
const processLanguage = file.processLanguage === "en" ? "en" : DEFAULT_PROCESS_LANGUAGE;
|
|
60
62
|
const config = {
|
|
61
63
|
enabled: file.enabled !== false,
|
|
62
64
|
botId: botId ?? "",
|
|
@@ -67,6 +69,7 @@ export function resolvePalzConfig(_cfg, botId) {
|
|
|
67
69
|
sessionTimeout: file.sessionTimeout ?? DEFAULT_SESSION_TIMEOUT,
|
|
68
70
|
groupContextCache: file.groupContextCache !== false,
|
|
69
71
|
showProcess: file.showProcess === true,
|
|
72
|
+
processLanguage,
|
|
70
73
|
kbEngineUrl: file.kbEngineUrl || "",
|
|
71
74
|
controlPort: file.controlPort,
|
|
72
75
|
};
|
package/src/gateway-relay.js
CHANGED
|
@@ -243,15 +243,16 @@ function modelResponseFromGatewayData(data) {
|
|
|
243
243
|
return new Response(body, { status, headers: { "Content-Type": contentType } });
|
|
244
244
|
}
|
|
245
245
|
async function relayOpenClawRequest(input, url, init, relay) {
|
|
246
|
+
const inboundHeaders = headersFromFetchInput(input, init);
|
|
247
|
+
if (isGatewayOpenClawAgentRelayHop(inboundHeaders)) {
|
|
248
|
+
relay.log?.("[GATEWAY_RELAY] skip gateway-originated OpenClaw agent relay hop; continuing locator model fetch");
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
246
251
|
const requestBody = await requestBodyFromFetchInput(input, init);
|
|
247
252
|
if (!normalize(relay.relayUrl))
|
|
248
253
|
throw new Error(gatewayRelayNotConfiguredError);
|
|
249
254
|
if (!requestBody)
|
|
250
255
|
throw new Error("failed to capture OpenClaw request body for palz gateway relay");
|
|
251
|
-
const inboundHeaders = headersFromFetchInput(input, init);
|
|
252
|
-
if (isGatewayOpenClawAgentRelayHop(inboundHeaders)) {
|
|
253
|
-
throw new Error("palz gateway relay captured gateway-originated OpenClaw agent hop");
|
|
254
|
-
}
|
|
255
256
|
const headers = { "Content-Type": "application/json" };
|
|
256
257
|
if (normalize(relay.apiKey))
|
|
257
258
|
headers["X-API-Key"] = normalize(relay.apiKey);
|
|
@@ -300,7 +301,8 @@ async function relayOpenClawRequest(input, url, init, relay) {
|
|
|
300
301
|
const parsed = parseGatewayRelayResponseText(raw);
|
|
301
302
|
const data = parsed?.data ? parsed.data : parsed;
|
|
302
303
|
if (data?.skippedInternalRelay) {
|
|
303
|
-
|
|
304
|
+
relay.log?.(`[GATEWAY_RELAY] gateway relay skipped internal OpenClaw agent loop reason=${normalize(data.skipReason)}; continuing locator model fetch`);
|
|
305
|
+
return null;
|
|
304
306
|
}
|
|
305
307
|
if (!resp.ok || !data || data.ok === false) {
|
|
306
308
|
throw new Error(`gateway relay failed status=${resp.status} body=${raw.slice(0, 500)}`);
|
|
@@ -324,7 +326,10 @@ export function installPalzGatewayRelayFetchPatch() {
|
|
|
324
326
|
return originalFetch(input, init);
|
|
325
327
|
}
|
|
326
328
|
const nextInit = withLocatorHeaders(init, relay);
|
|
327
|
-
|
|
329
|
+
const relayResponse = await relayOpenClawRequest(input, requestURL(input), nextInit, relay);
|
|
330
|
+
if (relayResponse)
|
|
331
|
+
return relayResponse;
|
|
332
|
+
return originalFetch(input, nextInit);
|
|
328
333
|
};
|
|
329
334
|
fetchPatched = true;
|
|
330
335
|
}
|
package/src/reply-dispatcher.js
CHANGED
|
@@ -27,6 +27,7 @@ export function createPalzReplyDispatcher(params) {
|
|
|
27
27
|
const error = typeof runtime?.error === "function" ? runtime.error : console.error;
|
|
28
28
|
const streamState = enableStreaming ? createStreamingState() : null;
|
|
29
29
|
const tag = `palz[${accountId}]`;
|
|
30
|
+
const processLanguage = config.processLanguage;
|
|
30
31
|
// 风控状态(dispatcher 实例级):当前正文回复(palzMsgType===undefined)命中腾讯
|
|
31
32
|
// 内容风控(80001)时置位,rawError 保留原始错误文案供上层回灌给 agent 做规避指引。
|
|
32
33
|
// 每个 dispatcher 实例对应一轮 dispatch,新实例自动重置。
|
|
@@ -114,14 +115,14 @@ export function createPalzReplyDispatcher(params) {
|
|
|
114
115
|
const toolName = data.name ?? data.toolName;
|
|
115
116
|
if (phase === "start") {
|
|
116
117
|
const display = resolveToolDisplay(toolName, data.args);
|
|
117
|
-
const text = formatToolStartText(toolName, data.args);
|
|
118
|
+
const text = formatToolStartText(toolName, data.args, processLanguage);
|
|
118
119
|
log(`${tag}: [TOOL_EVENTS] tool_start name=${toolName} detail=${display.detail ?? "(none)"}`);
|
|
119
120
|
enqueueIMSend(text, undefined, "tool_start", "tool_start");
|
|
120
121
|
}
|
|
121
122
|
if (phase === "result") {
|
|
122
123
|
const isError = data.isError === true;
|
|
123
124
|
const meta = typeof data.meta === "string" ? data.meta : undefined;
|
|
124
|
-
const text = formatToolResultText(toolName, data.result, isError, meta);
|
|
125
|
+
const text = formatToolResultText(toolName, data.result, isError, meta, processLanguage);
|
|
125
126
|
const resultSummary = isError ? "Error" : formatResultSummary(data.result);
|
|
126
127
|
log(`${tag}: [TOOL_EVENTS] tool_result name=${toolName} is_error=${isError} summary=${resultSummary}`);
|
|
127
128
|
enqueueIMSend(text, undefined, "tool_result", "tool_result");
|
package/src/tool-display.js
CHANGED
|
@@ -4,6 +4,30 @@
|
|
|
4
4
|
* 提供工具名到 emoji/title/detailKeys 的映射,以及生成纯文本摘要和结构化内容的辅助函数。
|
|
5
5
|
* 参考 OpenClaw 的 tool-display-overrides.json 和 ui/tool-display.ts。
|
|
6
6
|
*/
|
|
7
|
+
const TOOL_DISPLAY_LABELS = {
|
|
8
|
+
zh: {
|
|
9
|
+
startSuffix: "开始调用",
|
|
10
|
+
argsLabel: "参数",
|
|
11
|
+
completedSuffix: "调用完成",
|
|
12
|
+
resultLabel: "调用结果",
|
|
13
|
+
successText: "成功",
|
|
14
|
+
failedText: "失败",
|
|
15
|
+
errorLabel: "错误信息",
|
|
16
|
+
summaryLabel: "结果摘要",
|
|
17
|
+
successFallbackSuffix: "执行成功",
|
|
18
|
+
},
|
|
19
|
+
en: {
|
|
20
|
+
startSuffix: "started",
|
|
21
|
+
argsLabel: "Arguments",
|
|
22
|
+
completedSuffix: "completed",
|
|
23
|
+
resultLabel: "Result",
|
|
24
|
+
successText: "success",
|
|
25
|
+
failedText: "failed",
|
|
26
|
+
errorLabel: "Error",
|
|
27
|
+
summaryLabel: "Summary",
|
|
28
|
+
successFallbackSuffix: "succeeded",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
7
31
|
const TOOL_DISPLAY_MAP = {
|
|
8
32
|
web_search: { emoji: "🔎", title: "Web Search", detailKeys: ["query", "count"] },
|
|
9
33
|
web_fetch: { emoji: "📄", title: "Web Fetch", detailKeys: ["url", "extractMode", "maxChars"] },
|
|
@@ -47,6 +71,9 @@ export function truncateText(text, headLen = 80, tailLen = 40) {
|
|
|
47
71
|
return text;
|
|
48
72
|
return `${text.slice(0, headLen)}...${text.slice(-tailLen)}`;
|
|
49
73
|
}
|
|
74
|
+
function resolveLanguage(language) {
|
|
75
|
+
return language === "en" ? "en" : "zh";
|
|
76
|
+
}
|
|
50
77
|
// ============ Detail 提取 ============
|
|
51
78
|
function extractDetail(args, detailKeys) {
|
|
52
79
|
if (!args || typeof args !== "object" || !detailKeys.length)
|
|
@@ -115,28 +142,30 @@ export function resolveToolDisplay(name, args) {
|
|
|
115
142
|
return { emoji, title, detail };
|
|
116
143
|
}
|
|
117
144
|
// ============ 纯文本格式化 ============
|
|
118
|
-
export function formatToolStartText(name, args) {
|
|
145
|
+
export function formatToolStartText(name, args, language) {
|
|
119
146
|
const display = resolveToolDisplay(name, args);
|
|
120
|
-
const
|
|
147
|
+
const labels = TOOL_DISPLAY_LABELS[resolveLanguage(language)];
|
|
148
|
+
const lines = [`${display.emoji} ${display.title} ${labels.startSuffix}`];
|
|
121
149
|
if (display.detail) {
|
|
122
|
-
lines.push(
|
|
150
|
+
lines.push(`${labels.argsLabel}: ${display.detail}`);
|
|
123
151
|
}
|
|
124
152
|
return lines.join("\n");
|
|
125
153
|
}
|
|
126
|
-
export function formatToolResultText(name, result, isError, meta) {
|
|
154
|
+
export function formatToolResultText(name, result, isError, meta, language) {
|
|
127
155
|
const display = resolveToolDisplay(name);
|
|
128
|
-
const
|
|
156
|
+
const labels = TOOL_DISPLAY_LABELS[resolveLanguage(language)];
|
|
157
|
+
const lines = [`${display.emoji} ${display.title} ${labels.completedSuffix}`];
|
|
129
158
|
if (isError) {
|
|
130
|
-
lines.push(
|
|
159
|
+
lines.push(`${labels.resultLabel}: ${labels.failedText}`);
|
|
131
160
|
const errMsg = extractErrorMessage(result);
|
|
132
161
|
if (errMsg) {
|
|
133
|
-
lines.push(
|
|
162
|
+
lines.push(`${labels.errorLabel}: ${truncateText(errMsg, 80, 40)}`);
|
|
134
163
|
}
|
|
135
164
|
}
|
|
136
165
|
else {
|
|
137
|
-
lines.push(
|
|
138
|
-
const resultMeta = meta ? truncateText(meta, 120, 40) : `${display.title}
|
|
139
|
-
lines.push(
|
|
166
|
+
lines.push(`${labels.resultLabel}: ${labels.successText}`);
|
|
167
|
+
const resultMeta = meta ? truncateText(meta, 120, 40) : `${display.title} ${labels.successFallbackSuffix}`;
|
|
168
|
+
lines.push(`${labels.summaryLabel}: ${resultMeta}`);
|
|
140
169
|
}
|
|
141
170
|
return lines.join("\n");
|
|
142
171
|
}
|