claw-subagent-service 0.0.66 → 0.0.67
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/cli.js +15 -12
- package/package.json +1 -1
- package/service/daemon.js +13 -5
- package/service/rongcloud/openclaw-client.js +7 -1
package/cli.js
CHANGED
|
@@ -30,19 +30,22 @@ function runDaemon() {
|
|
|
30
30
|
console.log(`[CLI] Daemon 路径: ${DAEMON_PATH}`);
|
|
31
31
|
|
|
32
32
|
const daemon = spawn('node', [DAEMON_PATH], {
|
|
33
|
-
stdio: '
|
|
34
|
-
detached:
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
daemon.on('exit', (code) => {
|
|
38
|
-
console.log(`[CLI] Daemon 退出,code=${code}`);
|
|
39
|
-
process.exit(code);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
daemon.on('error', (err) => {
|
|
43
|
-
console.error(`[CLI] Daemon 启动失败: ${err.message}`);
|
|
44
|
-
process.exit(1);
|
|
33
|
+
stdio: 'ignore',
|
|
34
|
+
detached: true
|
|
45
35
|
});
|
|
36
|
+
|
|
37
|
+
daemon.unref();
|
|
38
|
+
|
|
39
|
+
// 不阻塞等待 Daemon 退出:
|
|
40
|
+
// detached: true 使 Daemon 成为独立进程组 leader,避免随 CLI 收到 SIGINT/SIGHUP;
|
|
41
|
+
// stdio: 'ignore' 防止 nohup 场景下 pipe 断开导致异常;
|
|
42
|
+
// unref() 让 CLI 事件循环不等待 Daemon,安装脚本可立即继续。
|
|
43
|
+
console.log(`[CLI] Daemon 已启动,PID=${daemon.pid}`);
|
|
44
|
+
|
|
45
|
+
// 短暂停留确认 Daemon 未立即崩溃,随后 CLI 退出(Daemon 继续后台运行)
|
|
46
|
+
setTimeout(() => {
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}, 1500);
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
function installService() {
|
package/package.json
CHANGED
package/service/daemon.js
CHANGED
|
@@ -49,8 +49,13 @@ function checkSingleton() {
|
|
|
49
49
|
log.error(`[DAEMON] 另一个 Daemon 实例已在运行 (PID: ${pid}, 权限不足),当前实例退出`);
|
|
50
50
|
return false;
|
|
51
51
|
}
|
|
52
|
-
//
|
|
52
|
+
// 进程不存在(ESRCH),清理 stale PID 文件
|
|
53
|
+
log.info(`[DAEMON] 发现 stale PID 文件 (PID: ${pid} 已不存在),清理中...`);
|
|
54
|
+
try { fs.unlinkSync(PID_FILE); } catch { /* 忽略 */ }
|
|
53
55
|
}
|
|
56
|
+
} else {
|
|
57
|
+
// PID 文件内容无效,清理
|
|
58
|
+
try { fs.unlinkSync(PID_FILE); } catch { /* 忽略 */ }
|
|
54
59
|
}
|
|
55
60
|
}
|
|
56
61
|
} catch {
|
|
@@ -129,7 +134,8 @@ function freePortIfNeeded(port) {
|
|
|
129
134
|
];
|
|
130
135
|
for (const cmd of commands) {
|
|
131
136
|
try {
|
|
132
|
-
|
|
137
|
+
// 精简 Docker 镜像中部分命令可能极慢或不存在,缩短超时避免阻塞
|
|
138
|
+
const out = execSync(cmd, { encoding: 'utf8', timeout: 2000 }).trim();
|
|
133
139
|
const firstLine = out.split(/\r?\n/)[0];
|
|
134
140
|
const candidate = parseInt(firstLine, 10);
|
|
135
141
|
if (candidate && candidate > 0 && candidate !== currentWorkerPid && candidate !== process.pid) {
|
|
@@ -148,7 +154,7 @@ function freePortIfNeeded(port) {
|
|
|
148
154
|
// 所有端口查询命令都不可用(常见于精简 Docker 镜像)
|
|
149
155
|
// 兜底:杀掉残留 Worker 进程(Daemon 自身的命令行不含 worker.js,不会自杀)
|
|
150
156
|
try {
|
|
151
|
-
execSync('pkill -9 -f "worker.js" 2>/dev/null || true', { timeout:
|
|
157
|
+
execSync('pkill -9 -f "worker.js" 2>/dev/null || true', { timeout: 2000 });
|
|
152
158
|
log.warn(`[DAEMON] 已尝试杀掉残留 Worker 进程`);
|
|
153
159
|
} catch { /* 忽略 */ }
|
|
154
160
|
}
|
|
@@ -340,8 +346,10 @@ function gracefulShutdown() {
|
|
|
340
346
|
worker = null;
|
|
341
347
|
}
|
|
342
348
|
|
|
343
|
-
//
|
|
344
|
-
freePortIfNeeded
|
|
349
|
+
// Worker 已被 SIGKILL,端口会立即释放,无需再执行可能阻塞的 freePortIfNeeded
|
|
350
|
+
// 旧代码在此处调用 freePortIfNeeded,其内部的 execSync 命令链在精简 Docker 中
|
|
351
|
+
// 可能阻塞 20+ 秒,导致 kill -15 后旧进程迟迟不退出,新实例 checkSingleton 失败。
|
|
352
|
+
cleanupPidFile();
|
|
345
353
|
process.exit(0);
|
|
346
354
|
}
|
|
347
355
|
|
|
@@ -411,9 +411,11 @@ class OpenClawClient {
|
|
|
411
411
|
{ role: 'user', content: message }
|
|
412
412
|
],
|
|
413
413
|
stream: true,
|
|
414
|
-
|
|
414
|
+
max_tokens: 2048
|
|
415
415
|
};
|
|
416
416
|
|
|
417
|
+
this.log?.info(`[OpenClawClient] SSE 请求 payload: ${JSON.stringify(payload)}`);
|
|
418
|
+
|
|
417
419
|
let fullText = '';
|
|
418
420
|
let buffer = '';
|
|
419
421
|
|
|
@@ -464,6 +466,10 @@ class OpenClawClient {
|
|
|
464
466
|
|
|
465
467
|
response.data.on('end', async () => {
|
|
466
468
|
this.log?.info(`[OpenClawClient] SSE 流结束,总长度: ${fullText.length}`);
|
|
469
|
+
if (fullText.length === 0) {
|
|
470
|
+
reject(new Error('OpenClaw SSE 返回空内容,可能模型未配置或 payload 格式不兼容'));
|
|
471
|
+
return;
|
|
472
|
+
}
|
|
467
473
|
try {
|
|
468
474
|
await onDone?.(fullText);
|
|
469
475
|
resolve();
|