claw-subagent-service 0.0.27 → 0.0.28

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claw-subagent-service",
3
- "version": "0.0.27",
3
+ "version": "0.0.28",
4
4
  "description": "虾说静态服务",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -122,9 +122,6 @@ class MessageHandler {
122
122
  this.sendReadReceiptFn(msg).catch(() => {});
123
123
  }
124
124
 
125
- // 先回复"正在处理",让用户知道消息已被接收
126
- this.sendFn(targetId, '🤖 正在思考中,请稍候...', msg.conversationType).catch(() => {});
127
-
128
125
  // 后台执行 openclaw,不阻塞消息队列
129
126
  this.openclawClient.chat(msg.content, msg.senderUserId)
130
127
  .then(reply => {
@@ -93,6 +93,38 @@ function getOpenClawEnv(baseEnv = process.env) {
93
93
  return env;
94
94
  }
95
95
 
96
+ /**
97
+ * 尝试读取 OpenClaw 的 gateway token
98
+ * openclaw agent 连接 gateway 需要认证,token 通常存储在配置文件中
99
+ */
100
+ function getGatewayToken() {
101
+ const homeDir = getRealHomeDir();
102
+ const possibleFiles = [
103
+ path.join(homeDir, '.openclaw', 'openclaw.json'),
104
+ path.join(homeDir, '.openclaw', 'config.json'),
105
+ path.join(homeDir, '.openclaw', 'tools.json'),
106
+ path.join(homeDir, '.openclaw', 'settings.json'),
107
+ ];
108
+
109
+ for (const filePath of possibleFiles) {
110
+ try {
111
+ if (fs.existsSync(filePath)) {
112
+ const content = fs.readFileSync(filePath, 'utf-8');
113
+ const config = JSON.parse(content);
114
+ // 可能的 token 字段名
115
+ const token = config.gatewayToken || config.token || config.apiKey || config.api_key || config.password;
116
+ if (token) {
117
+ return String(token);
118
+ }
119
+ }
120
+ } catch {
121
+ // 忽略读取/解析错误
122
+ }
123
+ }
124
+
125
+ return null;
126
+ }
127
+
96
128
  /**
97
129
  * 检测端口是否监听
98
130
  */
@@ -139,10 +171,9 @@ function startOpenClawGateway(log) {
139
171
  const interval = setInterval(async () => {
140
172
  attempts++;
141
173
  const gatewayRunning = await checkPort(18789);
142
- const apiRunning = await checkPort(5678);
143
174
  if (gatewayRunning) {
144
175
  clearInterval(interval);
145
- log?.info(`[OpenClawClient] OpenClaw gateway 启动成功 (18789),API 状态: ${apiRunning ? '就绪' : '未就绪'}`);
176
+ log?.info('[OpenClawClient] OpenClaw gateway 启动成功 (18789)');
146
177
  resolve(true);
147
178
  } else if (attempts >= maxAttempts) {
148
179
  clearInterval(interval);
@@ -173,30 +204,13 @@ class OpenClawClient {
173
204
  if (this.gatewayStarted) return true;
174
205
 
175
206
  const gatewayRunning = await checkPort(18789);
176
- const apiRunning = await checkPort(5678);
177
207
 
178
- if (gatewayRunning && apiRunning) {
179
- this.log?.info('[OpenClawClient] OpenClaw gateway API 均已就绪');
208
+ if (gatewayRunning) {
209
+ this.log?.info('[OpenClawClient] OpenClaw gateway 已在运行 (18789)');
180
210
  this.gatewayStarted = true;
181
211
  return true;
182
212
  }
183
213
 
184
- if (gatewayRunning && !apiRunning) {
185
- this.log?.info('[OpenClawClient] gateway 已运行 (18789),但 API (5678) 未就绪,继续等待...');
186
- // 等待最多 10 秒让 API 就绪
187
- for (let i = 0; i < 10; i++) {
188
- await new Promise(r => setTimeout(r, 1000));
189
- if (await checkPort(5678)) {
190
- this.log?.info('[OpenClawClient] API (5678) 已就绪');
191
- this.gatewayStarted = true;
192
- return true;
193
- }
194
- }
195
- this.log?.warn('[OpenClawClient] API (5678) 等待超时,gateway 可能未完全初始化');
196
- // gateway 在运行但 API 没好,仍然允许继续,让 HTTP fallback 到 CLI
197
- return true;
198
- }
199
-
200
214
  // 避免并发启动
201
215
  if (this.gatewayStarting) {
202
216
  this.log?.info('[OpenClawClient] gateway 正在启动中,等待...');
@@ -284,25 +298,33 @@ class OpenClawClient {
284
298
  .replace(/\n/g, ' ')
285
299
  .replace(/\r/g, ' ');
286
300
 
287
- const gatewayUrl = 'http://127.0.0.1:5678';
288
301
  const realHome = getRealHomeDir();
289
302
  this.log?.info(`[OpenClawClient] 使用用户目录: ${realHome}`);
290
303
 
304
+ // 尝试读取 gateway token,解决 SYSTEM 账户下认证问题
305
+ const gatewayToken = getGatewayToken();
306
+ if (gatewayToken) {
307
+ this.log?.info('[OpenClawClient] 已读取到 gateway token');
308
+ }
309
+
291
310
  const args = ['agent', '-m', escapedMessage, '--session-id', sessionId];
292
- this.log?.info(`[OpenClawClient] 执行: openclaw ${args.join(' ')}`);
311
+ if (gatewayToken) {
312
+ args.push('--token', gatewayToken);
313
+ }
314
+
315
+ this.log?.info(`[OpenClawClient] 执行: openclaw ${args.map(a => a.includes(' ') ? `"${a}"` : a).join(' ')}`);
293
316
 
294
317
  return new Promise((resolve) => {
295
318
  let stdout = '';
296
319
  let stderr = '';
297
320
  let killed = false;
298
321
 
322
+ // 关键:不设置 OPENCLAW_GATEWAY_URL,避免触发 "gateway url override requires explicit credentials"
323
+ // 让 openclaw agent 通过默认方式自动发现本地 gateway
299
324
  const child = spawn('openclaw', args, {
300
325
  shell: true,
301
326
  windowsHide: true,
302
- env: {
303
- ...getOpenClawEnv(),
304
- OPENCLAW_GATEWAY_URL: gatewayUrl,
305
- },
327
+ env: getOpenClawEnv(),
306
328
  });
307
329
 
308
330
  this.log?.info(`[OpenClawClient] CLI 子进程 PID=${child.pid}`);
@@ -314,15 +336,15 @@ class OpenClawClient {
314
336
  const text = chunk.toString();
315
337
  stderr += text;
316
338
  // 实时记录 stderr,方便调试卡死问题
317
- this.log?.info(`[OpenClawClient] CLI stderr: ${text.trim().substring(0, 200)}`);
339
+ this.log?.info(`[OpenClawClient] CLI stderr: ${text.trim().substring(0, 300)}`);
318
340
  });
319
341
 
320
- // 超时兜底(2 分钟)
342
+ // 超时兜底(30 秒)
321
343
  const timeout = setTimeout(() => {
322
344
  killed = true;
323
345
  child.kill('SIGTERM');
324
- this.log?.error('[OpenClawClient] CLI 执行超时(2分钟),强制终止');
325
- }, 120000);
346
+ this.log?.error('[OpenClawClient] CLI 执行超时(30秒),强制终止');
347
+ }, 30000);
326
348
 
327
349
  child.on('error', (err) => {
328
350
  clearTimeout(timeout);
@@ -338,7 +360,7 @@ class OpenClawClient {
338
360
  clearTimeout(timeout);
339
361
 
340
362
  if (killed) {
341
- resolve('OpenClaw CLI 响应超时');
363
+ resolve('OpenClaw 响应超时(30秒),请检查 openclaw 服务状态');
342
364
  return;
343
365
  }
344
366
 
@@ -348,7 +370,7 @@ class OpenClawClient {
348
370
  if (code !== 0) {
349
371
  const errOutput = stderr || stdout || '';
350
372
  this.log?.error(`[OpenClawClient] CLI 错误输出: ${errOutput.substring(0, 500)}`);
351
- resolve(`OpenClaw CLI 调用失败: ${errOutput.substring(0, 200)}`);
373
+ resolve(`OpenClaw 调用失败: ${errOutput.substring(0, 200)}`);
352
374
  return;
353
375
  }
354
376