claw-subagent-service 0.0.60 → 0.0.61
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/package.json +1 -1
- package/service/modules/config.js +13 -1
- package/service/rongcloud/openclaw-client.js +44 -23
- package/service/worker.js +15 -1
package/package.json
CHANGED
|
@@ -60,6 +60,18 @@ function loadConfig() {
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
|
|
63
|
+
// 计算 apiBaseUrl:环境变量 > 配置文件 > 推导值 > 默认值
|
|
64
|
+
let apiBaseUrl = process.env.API_BASE_URL || localConfig.apiBaseUrl || clawBridgeConfig.apiBaseUrl;
|
|
65
|
+
if (!apiBaseUrl) {
|
|
66
|
+
const serverUrl = process.env.DM_SERVER_URL || 'https://newsradar.dreamdt.cn/im';
|
|
67
|
+
try {
|
|
68
|
+
const url = new URL(serverUrl);
|
|
69
|
+
apiBaseUrl = `${url.protocol}//${url.host}`;
|
|
70
|
+
} catch {
|
|
71
|
+
apiBaseUrl = 'http://127.0.0.1:5000';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
63
75
|
return {
|
|
64
76
|
appKey: process.env.DM_APP_KEY || localConfig.appKey || 'bmdehs6pbyyks',
|
|
65
77
|
token: localConfig.token || clawBridgeConfig.token,
|
|
@@ -73,7 +85,7 @@ function loadConfig() {
|
|
|
73
85
|
scriptTimeout: localConfig.scriptTimeout || 180,
|
|
74
86
|
successKeyword: localConfig.successKeyword || 'Success',
|
|
75
87
|
chatTimeout: localConfig.chatTimeout || 600,
|
|
76
|
-
apiBaseUrl
|
|
88
|
+
apiBaseUrl
|
|
77
89
|
};
|
|
78
90
|
}
|
|
79
91
|
|
|
@@ -311,8 +311,35 @@ class OpenClawClient {
|
|
|
311
311
|
|
|
312
312
|
const gatewayToken = getGatewayToken();
|
|
313
313
|
const sessionId = `clawmessenger-${fromUser}`;
|
|
314
|
-
const apiUrl = 'http://127.0.0.1:18789/v1/chat/completions';
|
|
315
314
|
|
|
315
|
+
// 尝试多个可能的 SSE 端点,兼容不同版本 OpenClaw Gateway
|
|
316
|
+
const endpoints = [
|
|
317
|
+
'http://127.0.0.1:18789/v1/chat/completions',
|
|
318
|
+
'http://127.0.0.1:18789/v1/responses'
|
|
319
|
+
];
|
|
320
|
+
|
|
321
|
+
for (let i = 0; i < endpoints.length; i++) {
|
|
322
|
+
const apiUrl = endpoints[i];
|
|
323
|
+
try {
|
|
324
|
+
await this._doChatStream(apiUrl, gatewayToken, sessionId, message, onDelta, onDone);
|
|
325
|
+
return; // 成功则直接返回
|
|
326
|
+
} catch (err) {
|
|
327
|
+
const is404 = err.response?.status === 404;
|
|
328
|
+
const isLast = i === endpoints.length - 1;
|
|
329
|
+
|
|
330
|
+
if (is404 && !isLast) {
|
|
331
|
+
this.log?.warn(`[OpenClawClient] SSE 端点 ${apiUrl} 返回 404,尝试备用端点`);
|
|
332
|
+
continue;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
this.log?.error(`[OpenClawClient] SSE 请求失败: ${err.message}`);
|
|
336
|
+
onError?.(err);
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
async _doChatStream(apiUrl, gatewayToken, sessionId, message, onDelta, onDone) {
|
|
316
343
|
const headers = {
|
|
317
344
|
'Content-Type': 'application/json',
|
|
318
345
|
'Accept': 'text/event-stream'
|
|
@@ -333,13 +360,13 @@ class OpenClawClient {
|
|
|
333
360
|
let fullText = '';
|
|
334
361
|
let buffer = '';
|
|
335
362
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
});
|
|
363
|
+
const response = await axios.post(apiUrl, payload, {
|
|
364
|
+
headers,
|
|
365
|
+
responseType: 'stream',
|
|
366
|
+
timeout: 600000 // 10 分钟
|
|
367
|
+
});
|
|
342
368
|
|
|
369
|
+
return new Promise((resolve, reject) => {
|
|
343
370
|
response.data.on('data', (chunk) => {
|
|
344
371
|
buffer += chunk.toString();
|
|
345
372
|
const lines = buffer.split('\n');
|
|
@@ -365,23 +392,17 @@ class OpenClawClient {
|
|
|
365
392
|
}
|
|
366
393
|
});
|
|
367
394
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
resolve();
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
response.data.on('error', (err) => {
|
|
376
|
-
this.log?.error(`[OpenClawClient] SSE 流错误: ${err.message}`);
|
|
377
|
-
onError?.(err);
|
|
378
|
-
reject(err);
|
|
379
|
-
});
|
|
395
|
+
response.data.on('end', () => {
|
|
396
|
+
this.log?.info(`[OpenClawClient] SSE 流结束,总长度: ${fullText.length}`);
|
|
397
|
+
onDone?.(fullText);
|
|
398
|
+
resolve();
|
|
380
399
|
});
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
400
|
+
|
|
401
|
+
response.data.on('error', (err) => {
|
|
402
|
+
this.log?.error(`[OpenClawClient] SSE 流错误: ${err.message}`);
|
|
403
|
+
reject(err);
|
|
404
|
+
});
|
|
405
|
+
});
|
|
385
406
|
}
|
|
386
407
|
|
|
387
408
|
async chatViaCLI(message, fromUser) {
|
package/service/worker.js
CHANGED
|
@@ -184,6 +184,7 @@ function loadRongCloudConfig() {
|
|
|
184
184
|
config.token = clawConfig.token;
|
|
185
185
|
config.accountId = clawConfig.nodeId;
|
|
186
186
|
config.nodeName = clawConfig.nodeName;
|
|
187
|
+
if (clawConfig.apiBaseUrl) config.apiBaseUrl = clawConfig.apiBaseUrl;
|
|
187
188
|
log.info(`[WORKER] 从 claw-bridge 加载配置: nodeId=${clawConfig.nodeId}, nodeName=${clawConfig.nodeName}`);
|
|
188
189
|
} else {
|
|
189
190
|
log.warn(`[WORKER] 未找到 ${clawBridgeConfigPath}`);
|
|
@@ -199,6 +200,7 @@ function loadRongCloudConfig() {
|
|
|
199
200
|
if (localConfig.token) config.token = localConfig.token;
|
|
200
201
|
if (localConfig.accountId) config.accountId = localConfig.accountId;
|
|
201
202
|
if (localConfig.appSecret) config.appSecret = localConfig.appSecret;
|
|
203
|
+
if (localConfig.apiBaseUrl) config.apiBaseUrl = localConfig.apiBaseUrl;
|
|
202
204
|
log.info(`[WORKER] 从本地配置加载: appKey=${config.appKey?.substring(0, 8)}...`);
|
|
203
205
|
}
|
|
204
206
|
} catch (err) {
|
|
@@ -206,7 +208,19 @@ function loadRongCloudConfig() {
|
|
|
206
208
|
}
|
|
207
209
|
|
|
208
210
|
// 加载 apiBaseUrl(Python 后端地址,用于代理发送流式消息)
|
|
209
|
-
|
|
211
|
+
// 优先级:环境变量 > 配置文件 > 推导值(DM_SERVER_URL) > 默认值
|
|
212
|
+
config.apiBaseUrl = process.env.API_BASE_URL || config.apiBaseUrl;
|
|
213
|
+
|
|
214
|
+
if (!config.apiBaseUrl) {
|
|
215
|
+
const serverUrl = process.env.DM_SERVER_URL || 'https://newsradar.dreamdt.cn/im';
|
|
216
|
+
try {
|
|
217
|
+
const url = new URL(serverUrl);
|
|
218
|
+
config.apiBaseUrl = `${url.protocol}//${url.host}`;
|
|
219
|
+
log.info(`[WORKER] 从 serverUrl 推导 apiBaseUrl: ${config.apiBaseUrl}`);
|
|
220
|
+
} catch {
|
|
221
|
+
config.apiBaseUrl = 'http://127.0.0.1:5000';
|
|
222
|
+
}
|
|
223
|
+
}
|
|
210
224
|
|
|
211
225
|
if (!config.appKey) {
|
|
212
226
|
config.appKey = process.env.DM_APP_KEY || 'bmdehs6pbyyks';
|