claw-subagent-service 0.0.62 → 0.0.64

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.62",
3
+ "version": "0.0.64",
4
4
  "description": "虾说智能助手",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -153,11 +153,60 @@ function checkPort(port) {
153
153
  });
154
154
  }
155
155
 
156
+ /**
157
+ * 确保 openclaw.json 中启用了 chatCompletions 端点
158
+ * 在启动 gateway 前调用,避免 SSE 流式调用返回 404
159
+ */
160
+ function ensureChatCompletionsConfig(log) {
161
+ const realHome = getRealHomeDir();
162
+ const openclawDir = path.join(realHome, '.openclaw');
163
+ const configPath = path.join(openclawDir, 'openclaw.json');
164
+
165
+ let settings = {};
166
+ let existed = false;
167
+
168
+ try {
169
+ if (fs.existsSync(configPath)) {
170
+ const content = fs.readFileSync(configPath, 'utf-8');
171
+ settings = JSON.parse(content);
172
+ existed = true;
173
+ }
174
+ } catch (err) {
175
+ log?.warn(`[OpenClawClient] 读取 openclaw.json 失败: ${err.message}`);
176
+ settings = {};
177
+ }
178
+
179
+ const current = settings.gateway?.http?.endpoints?.chatCompletions?.enabled;
180
+ if (current === true) {
181
+ log?.info('[OpenClawClient] openclaw.json 中 chatCompletions 已启用');
182
+ return;
183
+ }
184
+
185
+ if (!settings.gateway) settings.gateway = {};
186
+ if (!settings.gateway.http) settings.gateway.http = {};
187
+ if (!settings.gateway.http.endpoints) settings.gateway.http.endpoints = {};
188
+ if (!settings.gateway.http.endpoints.chatCompletions) settings.gateway.http.endpoints.chatCompletions = {};
189
+ settings.gateway.http.endpoints.chatCompletions.enabled = true;
190
+
191
+ try {
192
+ if (!fs.existsSync(openclawDir)) {
193
+ fs.mkdirSync(openclawDir, { recursive: true });
194
+ }
195
+ fs.writeFileSync(configPath, JSON.stringify(settings, null, 2), 'utf-8');
196
+ log?.info(`[OpenClawClient] 已自动在 openclaw.json 中启用 chatCompletions (${existed ? '更新' : '新建'})`);
197
+ } catch (err) {
198
+ log?.error(`[OpenClawClient] 写入 openclaw.json 失败: ${err.message}`);
199
+ }
200
+ }
201
+
156
202
  /**
157
203
  * 启动 OpenClaw gateway
158
204
  */
159
205
  function startOpenClawGateway(log) {
160
206
  return new Promise((resolve) => {
207
+ // 启动前自动修复配置
208
+ ensureChatCompletionsConfig(log);
209
+
161
210
  log?.info('[OpenClawClient] 正在启动 OpenClaw gateway...');
162
211
 
163
212
  const child = spawn('openclaw', ['gateway'], {
@@ -230,8 +279,7 @@ class OpenClawClient {
230
279
  * 确保 OpenClaw gateway 在运行
231
280
  */
232
281
  async ensureGatewayRunning() {
233
- if (this.gatewayStarted) return true;
234
-
282
+ // 每次调用都实际检查端口,避免 gateway 崩溃后缓存状态失效
235
283
  const gatewayRunning = await checkPort(18789);
236
284
 
237
285
  if (gatewayRunning) {
@@ -240,6 +288,8 @@ class OpenClawClient {
240
288
  return true;
241
289
  }
242
290
 
291
+ this.gatewayStarted = false;
292
+
243
293
  // 避免并发启动
244
294
  if (this.gatewayStarting) {
245
295
  this.log?.info('[OpenClawClient] gateway 正在启动中,等待...');
@@ -332,7 +382,14 @@ class OpenClawClient {
332
382
  continue;
333
383
  }
334
384
 
335
- this.log?.error(`[OpenClawClient] SSE 请求失败: ${err.message}`);
385
+ if (is404 && isLast) {
386
+ this.log?.error(`[OpenClawClient] 所有 SSE 端点均返回 404。OpenClaw chatCompletions 端点未启用。`);
387
+ this.log?.error(`[OpenClawClient] 请检查 ~/.openclaw/openclaw.json 中是否包含:`);
388
+ this.log?.error(`[OpenClawClient] gateway.http.endpoints.chatCompletions.enabled = true`);
389
+ this.log?.error(`[OpenClawClient] 修改后请重启 OpenClaw gateway: openclaw gateway`);
390
+ } else {
391
+ this.log?.error(`[OpenClawClient] SSE 请求失败: ${err.message}`);
392
+ }
336
393
  // 不再内部调用 onError,让错误通过 Promise reject 向上传播,便于调用方回退
337
394
  throw err;
338
395
  }