claw-subagent-service 0.0.172 → 0.0.175
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 +5 -1
- package/scripts/unpublish.js +36 -0
- package/service/rongcloud/message-handler.js +21 -5
- package/service/worker.js +6 -98
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claw-subagent-service",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.175",
|
|
4
4
|
"description": "虾说智能助手",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"bin": {
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
"publish:patch": "npm version patch && npm publish",
|
|
16
16
|
"publish:minor": "npm version minor && npm publish",
|
|
17
17
|
"publish:major": "npm version major && npm publish",
|
|
18
|
+
"unpublish:last": "node scripts/unpublish.js",
|
|
19
|
+
"unpublish:version": "node scripts/unpublish.js",
|
|
20
|
+
"deprecate:last": "npm deprecate $(node -p \"require('./package.json').name\")@$(node -p \"require('./package.json').version\") \"This version is deprecated. Please upgrade.\"",
|
|
21
|
+
"deprecate:version": "npm deprecate",
|
|
18
22
|
"sync": "node scripts/sync-local.js"
|
|
19
23
|
},
|
|
20
24
|
"files": [
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// scripts/unpublish.js
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const { execSync } = require('child_process');
|
|
4
|
+
const pkg = require('../package.json');
|
|
5
|
+
|
|
6
|
+
const name = pkg.name;
|
|
7
|
+
const version = process.argv[2] || pkg.version;
|
|
8
|
+
const tag = `v${version}`;
|
|
9
|
+
|
|
10
|
+
console.log(`\n🗑️ Unpublishing ${name}@${version}...\n`);
|
|
11
|
+
|
|
12
|
+
// 1. 撤销 npm 包
|
|
13
|
+
try {
|
|
14
|
+
execSync(`npm unpublish ${name}@${version} --force`, { stdio: 'inherit' });
|
|
15
|
+
console.log(`✅ npm 撤销成功\n`);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.log(`⚠️ npm 撤销失败(可能已撤销或超时)\n`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// 2. 删除 git tag
|
|
21
|
+
try { execSync(`git tag -d ${tag}`, { stdio: 'pipe' }); console.log(`✅ 本地 tag ${tag} 已删除`); }
|
|
22
|
+
catch (e) { console.log(`⚠️ 本地 tag ${tag} 不存在`); }
|
|
23
|
+
|
|
24
|
+
try { execSync(`git push origin :refs/tags/${tag}`, { stdio: 'pipe' }); console.log(`✅ 远程 tag ${tag} 已删除`); }
|
|
25
|
+
catch (e) { console.log(`⚠️ 远程 tag ${tag} 不存在或无权限`); }
|
|
26
|
+
|
|
27
|
+
// 3. ⭐ 回退 package.json 版本(patch 级别减 1)
|
|
28
|
+
const parts = version.split('.').map(Number);
|
|
29
|
+
parts[2] = Math.max(0, parts[2] - 1); // patch - 1,最低为 0
|
|
30
|
+
const newVersion = parts.join('.');
|
|
31
|
+
|
|
32
|
+
pkg.version = newVersion;
|
|
33
|
+
fs.writeFileSync('./package.json', JSON.stringify(pkg, null, 2) + '\n');
|
|
34
|
+
|
|
35
|
+
console.log(`\n📦 package.json 版本已回退: ${version} → ${newVersion}`);
|
|
36
|
+
console.log(`🎉 清理完成!现在可以重新 publish:patch 了\n`);
|
|
@@ -720,14 +720,30 @@ class MessageHandler {
|
|
|
720
720
|
let remoteUrl = '';
|
|
721
721
|
let duration = 0;
|
|
722
722
|
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
723
|
+
// 先尝试解析 content(可能是 JSON 字符串)
|
|
724
|
+
let parsedContent = content;
|
|
725
|
+
if (typeof content === 'string' && content.startsWith('{')) {
|
|
726
|
+
try {
|
|
727
|
+
parsedContent = JSON.parse(content);
|
|
728
|
+
} catch (e) {
|
|
729
|
+
// 解析失败,保持原样
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
if (typeof parsedContent === 'object' && parsedContent !== null) {
|
|
734
|
+
remoteUrl = parsedContent.remoteUrl || parsedContent.url || '';
|
|
735
|
+
duration = parsedContent.duration || 0;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
// 兜底:从 msg 根对象查找
|
|
739
|
+
if (!remoteUrl) {
|
|
727
740
|
remoteUrl = msg.remoteUrl || msg.url || msg.localPath || '';
|
|
728
741
|
}
|
|
742
|
+
if (!duration) {
|
|
743
|
+
duration = msg.duration || 0;
|
|
744
|
+
}
|
|
729
745
|
|
|
730
|
-
this.log?.info(`[_extractMessageContent] 语音消息: remoteUrl=${remoteUrl}`);
|
|
746
|
+
this.log?.info(`[_extractMessageContent] 语音消息: remoteUrl=${remoteUrl}, duration=${duration}`);
|
|
731
747
|
return `[语音] ${remoteUrl} ${duration}秒`;
|
|
732
748
|
}
|
|
733
749
|
|
package/service/worker.js
CHANGED
|
@@ -303,108 +303,16 @@ async function refreshRongCloudToken() {
|
|
|
303
303
|
|
|
304
304
|
/**
|
|
305
305
|
* 从后端系统配置同步客服账号ID
|
|
306
|
-
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
* 设计原理:
|
|
310
|
-
* - 客服账号由管理员在系统配置表(im_system_config)中管理,支持频繁更新
|
|
311
|
-
* - silent-service 本地 config.json 的 nodeId 由 clawmessenger 注册时决定
|
|
312
|
-
* - 两者可能不一致,导致前端将消息发给 ID-A,但 silent-service 在 ID-B 上监听
|
|
313
|
-
* - 此函数在启动时拉取数据库配置,自动对齐
|
|
306
|
+
*
|
|
307
|
+
* 重要:节点服务保持独立,不强制切换为客服账号
|
|
308
|
+
* 客服账号仅用于专门的客服服务实例,不应影响普通节点服务
|
|
314
309
|
*
|
|
315
310
|
* @returns {Promise<boolean>} 配置是否已更新
|
|
316
311
|
*/
|
|
317
312
|
async function syncCustomerServiceAccountId() {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
try {
|
|
324
|
-
const resp = await axios.get(
|
|
325
|
-
`${rongcloudConfig.apiBaseUrl}/im/api/system/config/customer_service_account_id`,
|
|
326
|
-
{ timeout: 10000 }
|
|
327
|
-
);
|
|
328
|
-
|
|
329
|
-
if (resp.data?.code === 200 && resp.data?.data?.value) {
|
|
330
|
-
const csAccountId = resp.data.data.value;
|
|
331
|
-
const currentAccountId = rongcloudConfig.accountId;
|
|
332
|
-
|
|
333
|
-
if (csAccountId === currentAccountId) {
|
|
334
|
-
log.info(`[WORKER] 客服账号一致: ${csAccountId},无需变更`);
|
|
335
|
-
return false;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
log.info(`[WORKER] 客服账号不一致: 当前=${currentAccountId}, 数据库配置=${csAccountId},正在同步...`);
|
|
339
|
-
|
|
340
|
-
// 获取新账号的融云 token(节点必须已注册)
|
|
341
|
-
// 用独立 try-catch 包裹,与外部"配置不存在"的区分开
|
|
342
|
-
try {
|
|
343
|
-
const serverUrl = process.env.DM_SERVER_URL || 'https://newsradar.dreamdt.cn/im';
|
|
344
|
-
const tokenResp = await axios.get(
|
|
345
|
-
`${serverUrl}/api/claw/token/${csAccountId}`,
|
|
346
|
-
{ timeout: 15000 }
|
|
347
|
-
);
|
|
348
|
-
|
|
349
|
-
if (tokenResp.data?.code === 200) {
|
|
350
|
-
const newToken = tokenResp.data.data?.token || tokenResp.data.token || '';
|
|
351
|
-
const newAppKey = tokenResp.data.data?.app_key || tokenResp.data.app_key || '';
|
|
352
|
-
if (newToken) {
|
|
353
|
-
log.info(`[WORKER] 获取客服账号 token 成功: ${csAccountId}`);
|
|
354
|
-
|
|
355
|
-
// 更新内存配置(影响后续融云连接)
|
|
356
|
-
rongcloudConfig.accountId = csAccountId;
|
|
357
|
-
rongcloudConfig.token = newToken;
|
|
358
|
-
if (newAppKey) {
|
|
359
|
-
rongcloudConfig.appKey = newAppKey;
|
|
360
|
-
log.info(`[WORKER] 客服账号 appKey 已更新: ${newAppKey}`);
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
// 持久化到本地 config.json(确保重启后仍使用新配置)
|
|
364
|
-
try {
|
|
365
|
-
if (fs.existsSync(clawBridgeConfigPath)) {
|
|
366
|
-
const clawConfig = JSON.parse(fs.readFileSync(clawBridgeConfigPath, 'utf8'));
|
|
367
|
-
clawConfig.nodeId = csAccountId;
|
|
368
|
-
clawConfig.token = newToken;
|
|
369
|
-
if (newAppKey) {
|
|
370
|
-
clawConfig.appKey = newAppKey;
|
|
371
|
-
}
|
|
372
|
-
clawConfig.expiresAt = Date.now() + 7 * 24 * 60 * 60 * 1000; // 7天
|
|
373
|
-
fs.writeFileSync(clawBridgeConfigPath, JSON.stringify(clawConfig, null, 2));
|
|
374
|
-
log.info(`[WORKER] 客服账号已持久化到 config.json: ${csAccountId}`);
|
|
375
|
-
}
|
|
376
|
-
} catch (err) {
|
|
377
|
-
log.error(`[WORKER] 持久化客服账号到 config.json 失败: ${err.message}`);
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
return true;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
} catch (tokenErr) {
|
|
384
|
-
if (tokenErr.response?.status === 404) {
|
|
385
|
-
log.warn(`[WORKER] 客服账号 ${csAccountId} 未注册为 claw 节点,无法获取 token。请先使用 clawmessenger 注册该账号`);
|
|
386
|
-
} else {
|
|
387
|
-
log.warn(`[WORKER] 获取客服账号 token 失败: ${tokenErr.message}`);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
log.warn(`[WORKER] 保持当前配置: ${currentAccountId}`);
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// API 返回了非 200(如配置不存在时 404),静默忽略
|
|
396
|
-
return false;
|
|
397
|
-
} catch (err) {
|
|
398
|
-
// 网络错误在后端未就绪时常见,静默失败不影响启动
|
|
399
|
-
if (err.code === 'ECONNREFUSED' || err.code === 'ETIMEDOUT' || err.code === 'ENOTFOUND') {
|
|
400
|
-
log.warn(`[WORKER] 无法连接后端同步客服账号: ${err.message},保持当前配置`);
|
|
401
|
-
} else if (err.response?.status === 404) {
|
|
402
|
-
log.info('[WORKER] 客服账号未在系统配置中设置,使用当前配置');
|
|
403
|
-
} else {
|
|
404
|
-
log.error(`[WORKER] 同步客服账号异常: ${err.message}`);
|
|
405
|
-
}
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
313
|
+
// 节点服务保持独立,不切换客服账号
|
|
314
|
+
log.info(`[WORKER] 节点服务保持独立账号: ${rongcloudConfig?.accountId || 'unknown'},不切换客服账号`);
|
|
315
|
+
return false;
|
|
408
316
|
}
|
|
409
317
|
|
|
410
318
|
async function initRongCloud() {
|