claw-subagent-service 0.0.67 → 0.0.68

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.67",
3
+ "version": "0.0.68",
4
4
  "description": "虾说智能助手",
5
5
  "main": "cli.js",
6
6
  "bin": {
@@ -418,6 +418,9 @@ class OpenClawClient {
418
418
 
419
419
  let fullText = '';
420
420
  let buffer = '';
421
+ let lastChunkData = null;
422
+ let hasError = false;
423
+ let errorMsg = '';
421
424
 
422
425
  const response = await axios.post(apiUrl, payload, {
423
426
  headers,
@@ -440,23 +443,49 @@ class OpenClawClient {
440
443
 
441
444
  try {
442
445
  const data = JSON.parse(dataStr);
443
- // 尝试多个可能的内容字段,兼容不同版本 OpenClaw
444
- const delta = data.choices?.[0]?.delta?.content
445
- ?? data.choices?.[0]?.message?.content
446
- ?? data.choices?.[0]?.text
447
- ?? data.content
448
- ?? data.delta;
449
- if (typeof delta === 'string' && delta) {
450
- fullText += delta;
451
- try {
452
- await onDelta?.(delta);
453
- } catch (err) {
454
- reject(err);
455
- return;
446
+ lastChunkData = data;
447
+
448
+ // 检测流式错误块
449
+ if (data.error) {
450
+ hasError = true;
451
+ errorMsg = typeof data.error === 'string' ? data.error : (data.error.message || JSON.stringify(data.error));
452
+ this.log?.error(`[OpenClawClient] SSE chunk error: ${errorMsg}`);
453
+ continue;
454
+ }
455
+
456
+ // 尝试多个可能的内容字段,兼容不同版本 OpenClaw / 不同模型提供商
457
+ let delta = null;
458
+ const choice = data.choices?.[0];
459
+ if (choice) {
460
+ delta = choice.delta?.content
461
+ ?? choice.message?.content
462
+ ?? choice.text
463
+ ?? choice.delta?.text
464
+ ?? choice.delta?.reasoning_content
465
+ ?? null;
466
+ }
467
+ if (delta === null || delta === undefined) {
468
+ delta = data.content ?? data.delta ?? data.text ?? null;
469
+ }
470
+
471
+ if (typeof delta === 'string') {
472
+ if (delta.length > 0) {
473
+ fullText += delta;
474
+ try {
475
+ await onDelta?.(delta);
476
+ } catch (err) {
477
+ reject(err);
478
+ return;
479
+ }
456
480
  }
481
+ // 空字符串 delta 是合法的(无新内容块),静默跳过
482
+ } else if (delta !== null && delta !== undefined) {
483
+ this.log?.info(`[OpenClawClient] SSE 原始数据(delta非字符串): ${JSON.stringify(data).substring(0, 200)}`);
457
484
  } else {
458
- // 调试:打印未识别的 SSE 数据结构
459
- this.log?.info(`[OpenClawClient] SSE 原始数据(无delta): ${JSON.stringify(data).substring(0, 200)}`);
485
+ // 无可识别的 content 字段,仅当不包含 finish_reason 时才打印调试日志
486
+ if (!data.choices?.[0]?.finish_reason) {
487
+ this.log?.info(`[OpenClawClient] SSE 原始数据(无content): ${JSON.stringify(data).substring(0, 200)}`);
488
+ }
460
489
  }
461
490
  } catch {
462
491
  // 忽略无法解析的 JSON 行
@@ -466,8 +495,23 @@ class OpenClawClient {
466
495
 
467
496
  response.data.on('end', async () => {
468
497
  this.log?.info(`[OpenClawClient] SSE 流结束,总长度: ${fullText.length}`);
498
+
499
+ if (hasError) {
500
+ reject(new Error(`OpenClaw SSE 错误: ${errorMsg}`));
501
+ return;
502
+ }
503
+
504
+ if (fullText.length === 0) {
505
+ // 兜底:某些网关会在最后一个 chunk 的 message.content 中返回完整内容
506
+ const lastContent = lastChunkData?.choices?.[0]?.message?.content;
507
+ if (typeof lastContent === 'string' && lastContent.length > 0) {
508
+ fullText = lastContent;
509
+ this.log?.info(`[OpenClawClient] 从 last chunk message.content 提取内容,长度: ${fullText.length}`);
510
+ }
511
+ }
512
+
469
513
  if (fullText.length === 0) {
470
- reject(new Error('OpenClaw SSE 返回空内容,可能模型未配置或 payload 格式不兼容'));
514
+ reject(new Error('OpenClaw SSE 返回空内容,可能 LLM 网络异常或模型未配置'));
471
515
  return;
472
516
  }
473
517
  try {