@ganglion/weacpx-channel-feishu 0.2.0 → 0.2.1

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.
Files changed (2) hide show
  1. package/dist/index.js +57 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -80373,7 +80373,8 @@ class FeishuChannel {
80373
80373
  if (input.accountId && input.accountId !== route.accountId) {
80374
80374
  throw new Error(`scheduled Feishu accountId "${input.accountId}" does not match chatKey account "${route.accountId}"`);
80375
80375
  }
80376
- if (!this.accounts.has(route.accountId)) {
80376
+ const runtime = this.accounts.get(route.accountId);
80377
+ if (!runtime) {
80377
80378
  throw new Error(`feishu account "${route.accountId}" is not started; check channel.options.accounts and enabled flags`);
80378
80379
  }
80379
80380
  const deliverText = async (text) => {
@@ -80385,6 +80386,22 @@ class FeishuChannel {
80385
80386
  await this.sendRouteText(input.chatKey, input.replyContextToken, trimmed);
80386
80387
  };
80387
80388
  await this.sendRouteText(input.chatKey, input.replyContextToken, input.noticeText);
80389
+ const effectiveReplyMode = resolveEffectiveReplyMode(runtime.account.replyMode, undefined);
80390
+ const cardController = effectiveReplyMode === "streaming" ? await this.trySeedStreamingCard({
80391
+ runtime,
80392
+ accountId: route.accountId,
80393
+ chatId: route.chatId,
80394
+ ...input.replyContextToken ? { replyToMessageId: input.replyContextToken } : {}
80395
+ }) : null;
80396
+ const deliverReply = async (text) => {
80397
+ if (input.abortSignal?.aborted)
80398
+ return;
80399
+ if (cardController) {
80400
+ cardController.appendStream(text);
80401
+ return;
80402
+ }
80403
+ await deliverText(text);
80404
+ };
80388
80405
  try {
80389
80406
  const response = await this.agent.chat({
80390
80407
  accountId: route.accountId,
@@ -80393,10 +80410,26 @@ class FeishuChannel {
80393
80410
  ...input.replyContextToken ? { replyContextToken: input.replyContextToken } : {},
80394
80411
  ...input.abortSignal ? { abortSignal: input.abortSignal } : {},
80395
80412
  metadata: { channel: "feishu", scheduledSessionAlias: input.sessionAlias },
80396
- reply: deliverText
80413
+ reply: deliverReply,
80414
+ ...cardController ? {
80415
+ onToolEvent: (event) => {
80416
+ if (input.abortSignal?.aborted)
80417
+ return;
80418
+ cardController.recordToolEvent(event);
80419
+ },
80420
+ onThought: (chunk) => {
80421
+ if (input.abortSignal?.aborted)
80422
+ return;
80423
+ cardController.appendReasoning(chunk);
80424
+ }
80425
+ } : {}
80397
80426
  });
80398
- if (input.abortSignal?.aborted)
80427
+ if (input.abortSignal?.aborted) {
80428
+ if (cardController && !cardController.isTerminated()) {
80429
+ await cardController.abort(abortAck()).catch(() => {});
80430
+ }
80399
80431
  return;
80432
+ }
80400
80433
  const media = normalizeMediaArray(response.media);
80401
80434
  if (media.length > 0) {
80402
80435
  await this.logger.error("feishu.scheduled.media_unsupported", "scheduled feishu media responses are not supported", {
@@ -80407,11 +80440,23 @@ class FeishuChannel {
80407
80440
  count: media.length
80408
80441
  });
80409
80442
  }
80410
- await deliverText(response.text);
80443
+ if (cardController) {
80444
+ const responseText = response.text?.trim() ?? "";
80445
+ await cardController.complete(responseText.length > 0 ? response.text : undefined);
80446
+ if (cardController.isDegraded() && responseText.length > 0) {
80447
+ await deliverText(response.text);
80448
+ }
80449
+ } else {
80450
+ await deliverText(response.text);
80451
+ }
80411
80452
  } catch (error) {
80412
- try {
80413
- await deliverText(formatScheduledFailureText(input, error));
80414
- } catch {}
80453
+ if (cardController && !cardController.isTerminated()) {
80454
+ await cardController.fail(error instanceof Error ? error.message : String(error)).catch(() => {});
80455
+ } else {
80456
+ try {
80457
+ await deliverText(formatScheduledFailureText(input, error));
80458
+ } catch {}
80459
+ }
80415
80460
  throw error;
80416
80461
  }
80417
80462
  }
@@ -80593,7 +80638,7 @@ class FeishuChannel {
80593
80638
  return;
80594
80639
  const effectiveReplyMode = resolveEffectiveReplyMode(runtime.account.replyMode, chatType);
80595
80640
  if (effectiveReplyMode === "streaming") {
80596
- await this.trySeedStreamingCard({ runtime, accountId, chatId, messageId, active });
80641
+ active.cardController = await this.trySeedStreamingCard({ runtime, accountId, chatId, replyToMessageId: messageId });
80597
80642
  }
80598
80643
  if (active.suppressed) {
80599
80644
  if (active.cardController && !active.cardController.isTerminated()) {
@@ -80666,7 +80711,7 @@ class FeishuChannel {
80666
80711
  }
80667
80712
  }
80668
80713
  async trySeedStreamingCard(input) {
80669
- const { runtime, accountId, chatId, messageId, active } = input;
80714
+ const { runtime, accountId, chatId } = input;
80670
80715
  try {
80671
80716
  const controller = new StreamingCardController({
80672
80717
  client: runtime.client.sdk,
@@ -80681,8 +80726,8 @@ class FeishuChannel {
80681
80726
  this.logger?.error("feishu.card.degraded", "streaming card updates failing; will deliver answer via plain reply", { accountId, chatId, consecutiveFailures, bufferChars: buffer.length });
80682
80727
  }
80683
80728
  });
80684
- await controller.seed({ to: chatId, replyToMessageId: messageId });
80685
- active.cardController = controller;
80729
+ await controller.seed({ to: chatId, ...input.replyToMessageId ? { replyToMessageId: input.replyToMessageId } : {} });
80730
+ return controller;
80686
80731
  } catch (error) {
80687
80732
  const permErr = extractPermissionError(error);
80688
80733
  await this.logger.info("feishu.streaming.fallback", "streaming card seed failed; falling back to static", {
@@ -80693,7 +80738,7 @@ class FeishuChannel {
80693
80738
  });
80694
80739
  if (permErr)
80695
80740
  await this.maybeNotifyPermissionError({ runtime, chatId, error });
80696
- active.cardController = null;
80741
+ return null;
80697
80742
  }
80698
80743
  }
80699
80744
  async deliverResponse(input) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ganglion/weacpx-channel-feishu",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Feishu channel plugin for weacpx.",
5
5
  "license": "MIT",
6
6
  "keywords": ["weacpx", "feishu", "channel", "plugin"],