@openclaw/feishu 2026.5.7 → 2026.5.9-beta.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.
package/dist/api.js CHANGED
@@ -2,7 +2,7 @@ import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as bu
2
2
  import { n as createFeishuThreadBindingManager, r as getFeishuThreadBindingManager, t as __testing } from "./thread-bindings-BmS6TLes.js";
3
3
  import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-C3UhPVLV.js";
4
4
  import { r as listEnabledFeishuAccounts } from "./accounts-Ba3-WP1z.js";
5
- import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-BegH3cJm.js";
5
+ import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-C5kY2KFE.js";
6
6
  import { t as getFeishuRuntime } from "./runtime-CG0DuRCy.js";
7
7
  import { a as jsonToolResult, d as registerFeishuChatTools, f as createFeishuToolClient, m as resolveFeishuToolAccount, n as registerFeishuDriveTools, o as toolExecutionErrorResult, p as resolveAnyEnabledFeishuToolsConfig, s as unknownToolActionResult } from "./drive-C5eJLJr7.js";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/text-runtime";
@@ -10,6 +10,7 @@ import { existsSync } from "node:fs";
10
10
  import { homedir } from "node:os";
11
11
  import { basename, isAbsolute, resolve } from "node:path";
12
12
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
13
+ import { extensionForMime } from "openclaw/plugin-sdk/media-mime";
13
14
  import { Type } from "typebox";
14
15
  import { createClackPrompter } from "openclaw/plugin-sdk/setup-runtime";
15
16
  //#region extensions/feishu/src/doc-schema.ts
@@ -879,7 +880,7 @@ async function resolveUploadInput(url, filePath, maxBytes, localRoots, explicitF
879
880
  if (!header.includes(";base64")) throw new Error("Invalid data URI: missing ';base64' marker. Expected format: data:image/png;base64,<base64data>");
880
881
  const trimmedData = data.trim();
881
882
  if (trimmedData.length === 0 || !/^[A-Za-z0-9+/]+=*$/.test(trimmedData)) throw new Error(`Invalid data URI: base64 payload contains characters outside the standard alphabet.`);
882
- const ext = header.match(/data:([^;]+)/)?.[1]?.split("/")[1] ?? "png";
883
+ const ext = extensionForMime(header.match(/data:([^;]+)/)?.[1])?.slice(1) ?? "png";
883
884
  const estimatedBytes = Math.ceil(trimmedData.length * 3 / 4);
884
885
  if (estimatedBytes > maxBytes) throw new Error(`Image data URI exceeds limit: estimated ${estimatedBytes} bytes > ${maxBytes} bytes`);
885
886
  return {
@@ -1,7 +1,7 @@
1
1
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DWS3Ep2A.js";
2
2
  import { n as looksLikeFeishuId, r as normalizeFeishuTarget } from "./targets-JMFJRKSe.js";
3
3
  import { a as resolveDefaultFeishuAccountId, f as isRecord$1, i as listFeishuAccountIds, n as inspectFeishuCredentials, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-Ba3-WP1z.js";
4
- import "./card-interaction-BfRLgvw_.js";
4
+ import { n as createFeishuSendReceipt } from "./send-result-BVFTskB_.js";
5
5
  import { n as listFeishuDirectoryPeers, t as listFeishuDirectoryGroups } from "./directory.static-f3EeoRJd.js";
6
6
  import { t as messageActionTargetAliases } from "./security-audit-DqJdocrN.js";
7
7
  import { a as resolveFeishuGroupToolPolicy } from "./policy-D6c-wMPl.js";
@@ -14,6 +14,7 @@ import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
14
14
  import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
15
15
  import { adaptScopedAccountAccessor, createHybridChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
16
16
  import { buildChannelOutboundSessionRoute, createChatChannelPlugin, stripChannelTargetPrefix } from "openclaw/plugin-sdk/channel-core";
17
+ import { defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-message";
17
18
  import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
18
19
  import { createAllowlistProviderGroupPolicyWarningCollector, projectConfigAccountIdWarningCollector } from "openclaw/plugin-sdk/channel-policy";
19
20
  import { createChannelDirectoryAdapter, createRuntimeDirectoryLiveAdapter } from "openclaw/plugin-sdk/directory-runtime";
@@ -810,7 +811,37 @@ const meta = {
810
811
  aliases: ["lark"],
811
812
  order: 70
812
813
  };
813
- const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-DYsXcD36.js"), "feishuChannelRuntime");
814
+ const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-BK6_CcZk.js"), "feishuChannelRuntime");
815
+ function toFeishuMessageSendResult(result, kind) {
816
+ const receipt = result.receipt ?? createFeishuSendReceipt({
817
+ messageId: result.messageId,
818
+ chatId: result.chatId ?? "",
819
+ kind
820
+ });
821
+ return {
822
+ messageId: result.messageId || receipt.primaryPlatformMessageId,
823
+ receipt
824
+ };
825
+ }
826
+ const feishuMessageAdapter = defineChannelMessageAdapter({
827
+ id: "feishu",
828
+ durableFinal: { capabilities: {
829
+ text: true,
830
+ media: true
831
+ } },
832
+ send: {
833
+ text: async (ctx) => {
834
+ const sendText = (await loadFeishuChannelRuntime()).feishuOutbound.sendText;
835
+ if (!sendText) throw new Error("Feishu text sending is not available.");
836
+ return toFeishuMessageSendResult(await sendText(ctx), "text");
837
+ },
838
+ media: async (ctx) => {
839
+ const sendMedia = (await loadFeishuChannelRuntime()).feishuOutbound.sendMedia;
840
+ if (!sendMedia) throw new Error("Feishu media sending is not available.");
841
+ return toFeishuMessageSendResult(await sendMedia(ctx), "media");
842
+ }
843
+ }
844
+ });
814
845
  function buildFeishuPresentationCard(params) {
815
846
  const fallbackPresentation = {
816
847
  ...params.presentation.tone ? { tone: params.presentation.tone } : {},
@@ -1601,7 +1632,7 @@ const feishuPlugin = createChatChannelPlugin({
1601
1632
  })
1602
1633
  }),
1603
1634
  gateway: { startAccount: async (ctx) => {
1604
- const { monitorFeishuProvider } = await import("./monitor-BVR-x39Q.js");
1635
+ const { monitorFeishuProvider } = await import("./monitor-YkqtEXDP.js");
1605
1636
  const account = resolveFeishuRuntimeAccount({
1606
1637
  cfg: ctx.cfg,
1607
1638
  accountId: ctx.accountId
@@ -1618,7 +1649,8 @@ const feishuPlugin = createChatChannelPlugin({
1618
1649
  abortSignal: ctx.abortSignal,
1619
1650
  accountId: ctx.accountId
1620
1651
  });
1621
- } }
1652
+ } },
1653
+ message: feishuMessageAdapter
1622
1654
  },
1623
1655
  security: {
1624
1656
  collectWarnings: projectConfigAccountIdWarningCollector(collectFeishuSecurityWarnings),
@@ -1,2 +1,2 @@
1
- import { t as feishuPlugin } from "./channel-BegH3cJm.js";
1
+ import { t as feishuPlugin } from "./channel-C5kY2KFE.js";
2
2
  export { feishuPlugin };
@@ -1,17 +1,17 @@
1
1
  import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-Ba3-WP1z.js";
2
- import { r as createFeishuCardInteractionEnvelope } from "./card-interaction-BfRLgvw_.js";
2
+ import { s as createFeishuCardInteractionEnvelope } from "./send-result-BVFTskB_.js";
3
3
  import { n as listFeishuDirectoryPeers, t as listFeishuDirectoryGroups } from "./directory.static-f3EeoRJd.js";
4
4
  import { r as createFeishuClient } from "./client-DBVoQL5w.js";
5
5
  import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-C5eJLJr7.js";
6
6
  import { chunkTextForOutbound } from "./runtime-api.js";
7
- import { _ as shouldSuppressFeishuTextForVoiceMedia, a as sendCardFeishu, c as sendStructuredCardFeishu, g as sendMediaFeishu, i as resolveFeishuCardTemplate, n as getMessageFeishu, o as sendMarkdownCardFeishu, s as sendMessageFeishu, t as editMessageFeishu } from "./send-DowxxbpH.js";
7
+ import { a as sendCardFeishu, c as sendStructuredCardFeishu, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, n as getMessageFeishu, o as sendMarkdownCardFeishu, s as sendMessageFeishu, t as editMessageFeishu } from "./send-DKHEQrzH.js";
8
8
  import { t as probeFeishu } from "./probe-BNzzU_uR.js";
9
9
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
10
10
  import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
11
- import fs from "node:fs";
12
11
  import path from "node:path";
13
12
  import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
14
13
  import { resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
14
+ import { statRegularFileSync } from "openclaw/plugin-sdk/security-runtime";
15
15
  //#region extensions/feishu/src/directory.ts
16
16
  async function listFeishuDirectoryPeersLive(params) {
17
17
  const account = resolveFeishuAccount({
@@ -93,9 +93,8 @@ function normalizePossibleLocalImagePath(text) {
93
93
  ".tiff"
94
94
  ].includes(ext)) return null;
95
95
  if (!path.isAbsolute(raw)) return null;
96
- if (!fs.existsSync(raw)) return null;
97
96
  try {
98
- if (!fs.statSync(raw).isFile()) return null;
97
+ if (statRegularFileSync(raw).missing) return null;
99
98
  } catch {
100
99
  return null;
101
100
  }
@@ -3,7 +3,7 @@ import { l as fetchBotIdentityForMonitor } from "./monitor.state-DYM02ipp.js";
3
3
  //#region extensions/feishu/src/monitor.ts
4
4
  let monitorAccountRuntimePromise;
5
5
  async function loadMonitorAccountRuntime() {
6
- monitorAccountRuntimePromise ??= import("./monitor.account-CUZxYkjE.js");
6
+ monitorAccountRuntimePromise ??= import("./monitor.account-BRSlHEbU.js");
7
7
  return await monitorAccountRuntimePromise;
8
8
  }
9
9
  async function monitorFeishuProvider(opts = {}) {
@@ -2,17 +2,18 @@ import { t as buildFeishuConversationId } from "./conversation-id-DWS3Ep2A.js";
2
2
  import { i as resolveReceiveIdType } from "./targets-JMFJRKSe.js";
3
3
  import { n as createFeishuThreadBindingManager } from "./thread-bindings-BmS6TLes.js";
4
4
  import { _ as buildFeishuCommentTarget, f as isRecord$3, h as readString$2, l as encodeQuery, m as parseCommentContentElements, p as normalizeString, s as resolveFeishuRuntimeAccount, u as extractReplyText, v as normalizeCommentFileType } from "./accounts-Ba3-WP1z.js";
5
- import { i as decodeFeishuCardAction, n as buildFeishuCardActionTextFallback, r as createFeishuCardInteractionEnvelope } from "./card-interaction-BfRLgvw_.js";
5
+ import { c as decodeFeishuCardAction, o as buildFeishuCardActionTextFallback, s as createFeishuCardInteractionEnvelope } from "./send-result-BVFTskB_.js";
6
6
  import { i as resolveFeishuGroupConfig, n as isFeishuGroupAllowed, o as resolveFeishuReplyPolicy, r as resolveFeishuAllowlistMatch, t as hasExplicitFeishuGroupConfig } from "./policy-D6c-wMPl.js";
7
7
  import { t as getFeishuRuntime } from "./runtime-CG0DuRCy.js";
8
8
  import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-DBVoQL5w.js";
9
9
  import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-C5eJLJr7.js";
10
- import { buildAgentMediaPayload, createReplyPrefixContext, evaluateSupplementalContextVisibility, filterSupplementalContextItems, loadSessionStore, normalizeAgentId, resolveChannelContextVisibilityMode, resolveSessionStoreEntry } from "./runtime-api.js";
11
- import { _ as shouldSuppressFeishuTextForVoiceMedia, a as sendCardFeishu, c as sendStructuredCardFeishu, d as extractMentionTargets, f as isFeishuBroadcastMention, g as sendMediaFeishu, h as downloadMessageResourceFeishu, i as resolveFeishuCardTemplate, l as parsePostContent, m as isFeishuGroupChatType, n as getMessageFeishu, p as isMentionForwardRequest, r as listFeishuThreadMessages, s as sendMessageFeishu, u as buildMentionedCardContent, v as normalizeFeishuExternalKey } from "./send-DowxxbpH.js";
10
+ import { buildAgentMediaPayload, createReplyPrefixContext, evaluateSupplementalContextVisibility, filterSupplementalContextItems, loadSessionStore, normalizeAgentId as normalizeAgentId$1, resolveChannelContextVisibilityMode, resolveSessionStoreEntry } from "./runtime-api.js";
11
+ import { _ as normalizeFeishuExternalKey, a as sendCardFeishu, c as sendStructuredCardFeishu, d as isFeishuBroadcastMention, f as isMentionForwardRequest, g as shouldSuppressFeishuTextForVoiceMedia, h as sendMediaFeishu, i as resolveFeishuCardTemplate, l as parsePostContent, m as downloadMessageResourceFeishu, n as getMessageFeishu, p as isFeishuGroupChatType, r as listFeishuThreadMessages, s as sendMessageFeishu, u as extractMentionTargets } from "./send-DKHEQrzH.js";
12
12
  import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-BNzzU_uR.js";
13
13
  import { a as feishuWebhookRateLimiter, c as wsClients, i as botOpenIds, l as fetchBotIdentityForMonitor, n as FEISHU_WEBHOOK_MAX_BODY_BYTES, o as httpServers, r as botNames, s as recordWebhookStatus, t as FEISHU_WEBHOOK_BODY_TIMEOUT_MS } from "./monitor.state-DYM02ipp.js";
14
14
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, stripReasoningTagsFromText } from "openclaw/plugin-sdk/text-runtime";
15
15
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
16
+ import { createChannelMessageReplyPipeline } from "openclaw/plugin-sdk/channel-message";
16
17
  import { createChannelPairingController, createChannelPairingController as createChannelPairingController$1 } from "openclaw/plugin-sdk/channel-pairing";
17
18
  import { resolveAgentOutboundIdentity } from "openclaw/plugin-sdk/outbound-runtime";
18
19
  import fs from "node:fs";
@@ -20,16 +21,17 @@ import os from "node:os";
20
21
  import path from "node:path";
21
22
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
22
23
  import * as Lark from "@larksuiteoapi/node-sdk";
23
- import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
24
24
  import { createPersistentDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
25
25
  import { applyBasicWebhookRequestGuards } from "openclaw/plugin-sdk/webhook-ingress";
26
26
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
27
27
  import { resolveSendableOutboundReplyParts, resolveTextChunksWithFallback, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
28
+ import { resolveOpenDmAllowlistAccess, safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
28
29
  import * as crypto$1 from "node:crypto";
29
30
  import crypto from "node:crypto";
31
+ import { resolveChannelConfigWrites } from "openclaw/plugin-sdk/channel-config-writes";
30
32
  import { DEFAULT_GROUP_HISTORY_LIMIT, buildPendingHistoryContextFromMap, clearHistoryEntriesIfEnabled, recordPendingHistoryEntryIfEnabled } from "openclaw/plugin-sdk/reply-history";
31
33
  import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
32
- import { resolveOpenDmAllowlistAccess, safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
34
+ import { formatReasoningMessage } from "openclaw/plugin-sdk/agent-runtime";
33
35
  import { logTypingFailure } from "openclaw/plugin-sdk/channel-feedback";
34
36
  import { formatChannelProgressDraftLineForEntry, isChannelProgressDraftWorkToolName } from "openclaw/plugin-sdk/channel-streaming";
35
37
  import * as http from "node:http";
@@ -550,7 +552,14 @@ function resolveFeishuMessageDedupeKey(event) {
550
552
  * This creates a unique agent instance with its own workspace for each DM user.
551
553
  */
552
554
  async function maybeCreateDynamicAgent(params) {
553
- const { cfg, runtime, senderOpenId, dynamicCfg, log } = params;
555
+ const { cfg, runtime, senderOpenId, dynamicCfg, configWritesAllowed, log } = params;
556
+ if (!configWritesAllowed) {
557
+ log(`feishu: config writes disabled, not creating agent for ${senderOpenId}`);
558
+ return {
559
+ created: false,
560
+ updatedCfg: cfg
561
+ };
562
+ }
554
563
  const existingBindings = cfg.bindings ?? [];
555
564
  if (existingBindings.some((b) => b.match?.channel === "feishu" && b.match?.peer?.kind === "direct" && b.match?.peer?.id === senderOpenId)) return {
556
565
  created: false,
@@ -639,17 +648,30 @@ function resolveUserPath(p) {
639
648
  return p;
640
649
  }
641
650
  //#endregion
651
+ //#region extensions/feishu/src/agent-config.ts
652
+ const DEFAULT_AGENT_ID = "main";
653
+ function normalizeAgentId(value) {
654
+ return (value ?? "").trim().toLowerCase() || DEFAULT_AGENT_ID;
655
+ }
656
+ function resolveFeishuConfigReasoningDefault(cfg, agentId) {
657
+ const id = normalizeAgentId(agentId);
658
+ return cfg.agents?.list?.find((entry) => normalizeAgentId(entry?.id) === id)?.reasoningDefault ?? cfg.agents?.defaults?.reasoningDefault ?? "off";
659
+ }
660
+ //#endregion
642
661
  //#region extensions/feishu/src/reasoning-preview.ts
643
662
  function resolveFeishuReasoningPreviewEnabled(params) {
644
- if (!params.sessionKey) return false;
663
+ const configDefault = resolveFeishuConfigReasoningDefault(params.cfg, params.agentId);
664
+ if (!params.sessionKey) return configDefault === "stream";
645
665
  try {
646
- return resolveSessionStoreEntry({
666
+ const level = resolveSessionStoreEntry({
647
667
  store: loadSessionStore(params.storePath, { skipCache: true }),
648
668
  sessionKey: params.sessionKey
649
- }).existing?.reasoningLevel === "stream";
669
+ }).existing?.reasoningLevel;
670
+ if (level === "on" || level === "stream" || level === "off") return level === "stream";
650
671
  } catch {
651
672
  return false;
652
673
  }
674
+ return configDefault === "stream";
653
675
  }
654
676
  //#endregion
655
677
  //#region extensions/feishu/src/streaming-card.ts
@@ -1179,7 +1201,7 @@ function resolveCardNote(agentId, identity, prefixCtx) {
1179
1201
  }
1180
1202
  function createFeishuReplyDispatcher(params) {
1181
1203
  const core = getFeishuRuntime();
1182
- const { cfg, agentId, chatId, replyToMessageId, skipReplyToInMessages, replyInThread, threadReply, rootId, mentionTargets, accountId, identity } = params;
1204
+ const { cfg, agentId, chatId, replyToMessageId, skipReplyToInMessages, replyInThread, threadReply, rootId, accountId, identity } = params;
1183
1205
  const sendReplyToMessageId = skipReplyToInMessages ? void 0 : replyToMessageId;
1184
1206
  const effectiveReplyInThread = threadReply === true ? true : replyInThread;
1185
1207
  const account = resolveFeishuRuntimeAccount({
@@ -1191,7 +1213,7 @@ function createFeishuReplyDispatcher(params) {
1191
1213
  agentId
1192
1214
  });
1193
1215
  let typingState = null;
1194
- const { typingCallbacks } = createChannelReplyPipeline({
1216
+ const { typingCallbacks } = createChannelMessageReplyPipeline({
1195
1217
  cfg,
1196
1218
  agentId,
1197
1219
  channel: "feishu",
@@ -1329,8 +1351,7 @@ function createFeishuReplyDispatcher(params) {
1329
1351
  await partialUpdateQueue;
1330
1352
  if (streaming?.isActive()) {
1331
1353
  statusLine = "";
1332
- let text = buildCombinedStreamText(reasoningText, streamText);
1333
- if (mentionTargets?.length) text = buildMentionedCardContent(mentionTargets, text);
1354
+ const text = buildCombinedStreamText(reasoningText, streamText);
1334
1355
  const finalNote = resolveCardNote(agentId, identity, prefixContext.prefixContext);
1335
1356
  await streaming.close(text, { note: finalNote });
1336
1357
  if (streamText) {
@@ -1386,14 +1407,13 @@ function createFeishuReplyDispatcher(params) {
1386
1407
  text: options.fallbackText,
1387
1408
  useCard: false,
1388
1409
  infoKind: "final",
1389
- sendChunk: async ({ chunk, isFirst }) => {
1410
+ sendChunk: async ({ chunk }) => {
1390
1411
  await sendMessageFeishu({
1391
1412
  cfg,
1392
1413
  to: chatId,
1393
1414
  text: chunk,
1394
1415
  replyToMessageId: sendReplyToMessageId,
1395
1416
  replyInThread: effectiveReplyInThread,
1396
- mentions: isFirst ? mentionTargets : void 0,
1397
1417
  accountId
1398
1418
  });
1399
1419
  }
@@ -1407,14 +1427,13 @@ function createFeishuReplyDispatcher(params) {
1407
1427
  text: fallbackText,
1408
1428
  useCard: false,
1409
1429
  infoKind: "final",
1410
- sendChunk: async ({ chunk, isFirst }) => {
1430
+ sendChunk: async ({ chunk }) => {
1411
1431
  await sendMessageFeishu({
1412
1432
  cfg,
1413
1433
  to: chatId,
1414
1434
  text: chunk,
1415
1435
  replyToMessageId: sendReplyToMessageId,
1416
1436
  replyInThread: effectiveReplyInThread,
1417
- mentions: isFirst ? mentionTargets : void 0,
1418
1437
  accountId
1419
1438
  });
1420
1439
  }
@@ -1434,7 +1453,11 @@ function createFeishuReplyDispatcher(params) {
1434
1453
  await typingCallbacks?.onReplyStart?.();
1435
1454
  },
1436
1455
  deliver: async (payload, info) => {
1437
- const reply = resolveSendableOutboundReplyParts(payload);
1456
+ const payloadText = payload.isReasoning && payload.text ? formatReasoningMessage(payload.text) : payload.text;
1457
+ const reply = resolveSendableOutboundReplyParts({
1458
+ ...payload,
1459
+ text: payloadText
1460
+ });
1438
1461
  const text = reply.text;
1439
1462
  const hasText = reply.hasText;
1440
1463
  const hasMedia = reply.hasMedia;
@@ -1478,14 +1501,13 @@ function createFeishuReplyDispatcher(params) {
1478
1501
  text,
1479
1502
  useCard: true,
1480
1503
  infoKind: info?.kind,
1481
- sendChunk: async ({ chunk, isFirst }) => {
1504
+ sendChunk: async ({ chunk }) => {
1482
1505
  await sendStructuredCardFeishu({
1483
1506
  cfg,
1484
1507
  to: chatId,
1485
1508
  text: chunk,
1486
1509
  replyToMessageId: sendReplyToMessageId,
1487
1510
  replyInThread: effectiveReplyInThread,
1488
- mentions: isFirst ? mentionTargets : void 0,
1489
1511
  accountId,
1490
1512
  header: cardHeader,
1491
1513
  note: cardNote
@@ -1496,14 +1518,13 @@ function createFeishuReplyDispatcher(params) {
1496
1518
  text,
1497
1519
  useCard: false,
1498
1520
  infoKind: info?.kind,
1499
- sendChunk: async ({ chunk, isFirst }) => {
1521
+ sendChunk: async ({ chunk }) => {
1500
1522
  await sendMessageFeishu({
1501
1523
  cfg,
1502
1524
  to: chatId,
1503
1525
  text: chunk,
1504
1526
  replyToMessageId: sendReplyToMessageId,
1505
1527
  replyInThread: effectiveReplyInThread,
1506
- mentions: isFirst ? mentionTargets : void 0,
1507
1528
  accountId
1508
1529
  });
1509
1530
  }
@@ -1547,7 +1568,7 @@ function createFeishuReplyDispatcher(params) {
1547
1568
  onReasoningStream: reasoningPreviewEnabled ? (payload) => {
1548
1569
  if (!payload.text) return;
1549
1570
  startStreaming();
1550
- queueReasoningUpdate(payload.text);
1571
+ queueReasoningUpdate(formatReasoningMessage(payload.text));
1551
1572
  } : void 0,
1552
1573
  onReasoningEnd: reasoningPreviewEnabled ? () => {} : void 0,
1553
1574
  onToolStart: streamingEnabled ? (payload) => {
@@ -1696,6 +1717,14 @@ function parseFeishuMessageEvent(event, botOpenId, _botName) {
1696
1717
  }
1697
1718
  return ctx;
1698
1719
  }
1720
+ const MAX_MENTION_CONTEXT_NAME_LENGTH = 80;
1721
+ function formatMentionNameForAgentContext(name) {
1722
+ const normalized = Array.from(name, (char) => {
1723
+ return char.charCodeAt(0) < 32 || char === "[" || char === "]" ? " " : char;
1724
+ }).join("").replace(/\s+/g, " ").trim();
1725
+ const bounded = normalized.length > MAX_MENTION_CONTEXT_NAME_LENGTH ? `${normalized.slice(0, MAX_MENTION_CONTEXT_NAME_LENGTH - 3)}...` : normalized;
1726
+ return JSON.stringify(bounded || "unknown");
1727
+ }
1699
1728
  function buildFeishuAgentBody(params) {
1700
1729
  const { ctx, quotedContent, permissionErrorForAgent, botOpenId } = params;
1701
1730
  let messageBody = ctx.content;
@@ -1707,8 +1736,8 @@ function buildFeishuAgentBody(params) {
1707
1736
  if (botIdHint) messageBody += `\n[System: If user_id is "${botIdHint}", that mention refers to you.]`;
1708
1737
  }
1709
1738
  if (ctx.mentionTargets && ctx.mentionTargets.length > 0) {
1710
- const targetNames = ctx.mentionTargets.map((t) => t.name).join(", ");
1711
- messageBody += `\n\n[System: Your reply will automatically @mention: ${targetNames}. Do not write @xxx yourself.]`;
1739
+ const targetNames = ctx.mentionTargets.map((t) => formatMentionNameForAgentContext(t.name)).join(", ");
1740
+ messageBody += `\n\n[System: Feishu users mentioned in the incoming message, for context only: ${targetNames}. Do not notify or mention these users solely because they are listed here.]`;
1712
1741
  }
1713
1742
  messageBody = `[message_id: ${ctx.messageId}]\n${messageBody}`;
1714
1743
  if (permissionErrorForAgent) {
@@ -1875,7 +1904,7 @@ async function handleFeishuMessage(params) {
1875
1904
  const configAllowFrom = feishuCfg?.allowFrom ?? [];
1876
1905
  const useAccessGroups = cfg.commands?.useAccessGroups !== false;
1877
1906
  const rawBroadcastAgents = isGroup ? resolveBroadcastAgents(cfg, ctx.chatId) : null;
1878
- const broadcastAgents = rawBroadcastAgents ? [...new Set(rawBroadcastAgents.map((id) => normalizeAgentId(id)))] : null;
1907
+ const broadcastAgents = rawBroadcastAgents ? [...new Set(rawBroadcastAgents.map((id) => normalizeAgentId$1(id)))] : null;
1879
1908
  const messageCreateTimeMs = event.message.create_time ? Number.parseInt(event.message.create_time, 10) : Date.now();
1880
1909
  let requireMention = false;
1881
1910
  if (isGroup) {
@@ -2026,6 +2055,11 @@ async function handleFeishuMessage(params) {
2026
2055
  runtime: getFeishuRuntime(),
2027
2056
  senderOpenId: ctx.senderOpenId,
2028
2057
  dynamicCfg,
2058
+ configWritesAllowed: resolveChannelConfigWrites({
2059
+ cfg,
2060
+ channelId: "feishu",
2061
+ accountId: account.accountId
2062
+ }),
2029
2063
  log: (msg) => log(msg)
2030
2064
  });
2031
2065
  if (result.created) {
@@ -2353,12 +2387,12 @@ async function handleFeishuMessage(params) {
2353
2387
  return;
2354
2388
  }
2355
2389
  const strategy = cfg.broadcast?.strategy === "sequential" ? "sequential" : "parallel";
2356
- const activeAgentId = ctx.mentionedBot || !requireMention ? normalizeAgentId(route.agentId) : null;
2357
- const agentIds = (cfg.agents?.list ?? []).map((a) => normalizeAgentId(a.id));
2390
+ const activeAgentId = ctx.mentionedBot || !requireMention ? normalizeAgentId$1(route.agentId) : null;
2391
+ const agentIds = (cfg.agents?.list ?? []).map((a) => normalizeAgentId$1(a.id));
2358
2392
  const hasKnownAgents = agentIds.length > 0;
2359
2393
  log(`feishu[${account.accountId}]: broadcasting to ${broadcastAgents.length} agents (strategy=${strategy}, active=${activeAgentId ?? "none"})`);
2360
2394
  const dispatchForAgent = async (agentId) => {
2361
- if (hasKnownAgents && !agentIds.includes(normalizeAgentId(agentId))) {
2395
+ if (hasKnownAgents && !agentIds.includes(normalizeAgentId$1(agentId))) {
2362
2396
  log(`feishu[${account.accountId}]: broadcast agent ${agentId} not found in agents.list; skipping`);
2363
2397
  return;
2364
2398
  }
@@ -2368,6 +2402,8 @@ async function handleFeishuMessage(params) {
2368
2402
  log(`feishu[${account.accountId}]: failed to record broadcast inbound session ${agentSessionKey}: ${String(err)}`);
2369
2403
  } };
2370
2404
  const allowReasoningPreview = resolveFeishuReasoningPreviewEnabled({
2405
+ cfg,
2406
+ agentId,
2371
2407
  storePath: agentStorePath,
2372
2408
  sessionKey: agentSessionKey
2373
2409
  });
@@ -2385,7 +2421,6 @@ async function handleFeishuMessage(params) {
2385
2421
  replyInThread,
2386
2422
  rootId: ctx.rootId,
2387
2423
  threadReply,
2388
- mentionTargets: ctx.mentionTargets,
2389
2424
  accountId: account.accountId,
2390
2425
  identity,
2391
2426
  messageCreateTimeMs
@@ -2503,6 +2538,8 @@ async function handleFeishuMessage(params) {
2503
2538
  const identity = resolveAgentOutboundIdentity(cfg, route.agentId);
2504
2539
  const storePath = core.channel.session.resolveStorePath(cfg.session?.store, { agentId: route.agentId });
2505
2540
  const allowReasoningPreview = resolveFeishuReasoningPreviewEnabled({
2541
+ cfg,
2542
+ agentId: route.agentId,
2506
2543
  storePath,
2507
2544
  sessionKey: route.sessionKey
2508
2545
  });
@@ -2517,7 +2554,6 @@ async function handleFeishuMessage(params) {
2517
2554
  replyInThread,
2518
2555
  rootId: ctx.rootId,
2519
2556
  threadReply,
2520
- mentionTargets: ctx.mentionTargets,
2521
2557
  accountId: account.accountId,
2522
2558
  identity,
2523
2559
  messageCreateTimeMs
@@ -3999,6 +4035,11 @@ async function handleFeishuCommentEvent(params) {
3999
4035
  runtime: core,
4000
4036
  senderOpenId: turn.senderId,
4001
4037
  dynamicCfg,
4038
+ configWritesAllowed: resolveChannelConfigWrites({
4039
+ cfg: params.cfg,
4040
+ channelId: "feishu",
4041
+ accountId: account.accountId
4042
+ }),
4002
4043
  log: (message) => log(message)
4003
4044
  });
4004
4045
  if (dynamicResult.created) {
@@ -1,11 +1,11 @@
1
1
  import { n as setFeishuRuntime } from "./runtime-CG0DuRCy.js";
2
2
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
3
+ import { createReplyPrefixContext } from "openclaw/plugin-sdk/channel-message";
3
4
  import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
4
5
  import { PAIRING_APPROVED_MESSAGE, buildProbeChannelStatusSummary, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/channel-status";
5
6
  import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
6
7
  import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, createActionGate, createDedupeCache } from "openclaw/plugin-sdk/core";
7
8
  import { buildAgentMediaPayload } from "openclaw/plugin-sdk/agent-media-payload";
8
- import { createReplyPrefixContext } from "openclaw/plugin-sdk/channel-reply-pipeline";
9
9
  import { evaluateSupplementalContextVisibility, filterSupplementalContextItems, resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
10
10
  import { loadSessionStore, resolveSessionStoreEntry } from "openclaw/plugin-sdk/session-store-runtime";
11
11
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
@@ -1,14 +1,16 @@
1
1
  import { i as resolveReceiveIdType, r as normalizeFeishuTarget } from "./targets-JMFJRKSe.js";
2
2
  import { c as createFeishuApiError, f as isRecord$2, g as requestFeishuApi, s as resolveFeishuRuntimeAccount } from "./accounts-Ba3-WP1z.js";
3
+ import { i as toFeishuSendResult, r as resolveFeishuReceiptKind, t as assertFeishuMessageApiSuccess } from "./send-result-BVFTskB_.js";
3
4
  import { t as getFeishuRuntime } from "./runtime-CG0DuRCy.js";
4
5
  import { r as createFeishuClient } from "./client-DBVoQL5w.js";
5
6
  import { convertMarkdownTables, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/text-runtime";
6
7
  import fs from "node:fs";
7
8
  import path from "node:path";
9
+ import { mediaKindFromMime } from "openclaw/plugin-sdk/media-mime";
8
10
  import { MEDIA_FFMPEG_MAX_AUDIO_DURATION_SECS, runFfmpeg } from "openclaw/plugin-sdk/media-runtime";
11
+ import { readRegularFile, writeExternalFileWithinRoot } from "openclaw/plugin-sdk/security-runtime";
9
12
  import { Readable } from "node:stream";
10
- import { mediaKindFromMime } from "openclaw/plugin-sdk/media-mime";
11
- import { resolvePreferredOpenClawTmpDir, withTempDownloadPath } from "openclaw/plugin-sdk/temp-path";
13
+ import { resolvePreferredOpenClawTmpDir, withTempDownloadPath, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
12
14
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
13
15
  //#region extensions/feishu/src/external-keys.ts
14
16
  const CONTROL_CHARS_RE = /\p{Cc}/u;
@@ -22,17 +24,6 @@ function normalizeFeishuExternalKey(value) {
22
24
  return normalized;
23
25
  }
24
26
  //#endregion
25
- //#region extensions/feishu/src/send-result.ts
26
- function assertFeishuMessageApiSuccess(response, errorPrefix) {
27
- if (response.code !== 0) throw new Error(`${errorPrefix}: ${response.msg || `code ${response.code}`}`);
28
- }
29
- function toFeishuSendResult(response, chatId) {
30
- return {
31
- messageId: response.data?.message_id ?? "unknown",
32
- chatId
33
- };
34
- }
35
- //#endregion
36
27
  //#region extensions/feishu/src/send-target.ts
37
28
  function resolveFeishuSendTarget(params) {
38
29
  const target = params.to.trim();
@@ -237,7 +228,7 @@ async function uploadImageFeishu(params) {
237
228
  cfg,
238
229
  accountId
239
230
  });
240
- const imageData = typeof image === "string" ? fs.createReadStream(image) : image;
231
+ const imageData = typeof image === "string" ? (await readRegularFile({ filePath: image })).buffer : image;
241
232
  return { imageKey: extractFeishuUploadKey(await requestFeishuApi(() => client.im.image.create({ data: {
242
233
  image_type: imageType,
243
234
  image: imageData
@@ -269,7 +260,7 @@ async function uploadFileFeishu(params) {
269
260
  cfg,
270
261
  accountId
271
262
  });
272
- const fileData = typeof file === "string" ? fs.createReadStream(file) : file;
263
+ const fileData = typeof file === "string" ? (await readRegularFile({ filePath: file })).buffer : file;
273
264
  const safeFileName = sanitizeFileNameForUpload(fileName);
274
265
  return { fileKey: extractFeishuUploadKey(await requestFeishuApi(() => client.im.file.create({ data: {
275
266
  file_type: fileType,
@@ -302,7 +293,7 @@ async function sendImageFeishu(params) {
302
293
  }
303
294
  }), "Feishu image reply failed", { includeNestedErrorLogId: true });
304
295
  assertFeishuMessageApiSuccess(response, "Feishu image reply failed");
305
- return toFeishuSendResult(response, receiveId);
296
+ return toFeishuSendResult(response, receiveId, "media");
306
297
  }
307
298
  const response = await requestFeishuApi(() => client.im.message.create({
308
299
  params: { receive_id_type: receiveIdType },
@@ -313,7 +304,7 @@ async function sendImageFeishu(params) {
313
304
  }
314
305
  }), "Feishu image send failed", { includeNestedErrorLogId: true });
315
306
  assertFeishuMessageApiSuccess(response, "Feishu image send failed");
316
- return toFeishuSendResult(response, receiveId);
307
+ return toFeishuSendResult(response, receiveId, "media");
317
308
  }
318
309
  /**
319
310
  * Send a file message using a file_key
@@ -337,7 +328,7 @@ async function sendFileFeishu(params) {
337
328
  }
338
329
  }), "Feishu file reply failed", { includeNestedErrorLogId: true });
339
330
  assertFeishuMessageApiSuccess(response, "Feishu file reply failed");
340
- return toFeishuSendResult(response, receiveId);
331
+ return toFeishuSendResult(response, receiveId, resolveFeishuReceiptKind(msgType));
341
332
  }
342
333
  const response = await requestFeishuApi(() => client.im.message.create({
343
334
  params: { receive_id_type: receiveIdType },
@@ -348,7 +339,7 @@ async function sendFileFeishu(params) {
348
339
  }
349
340
  }), "Feishu file send failed", { includeNestedErrorLogId: true });
350
341
  assertFeishuMessageApiSuccess(response, "Feishu file send failed");
351
- return toFeishuSendResult(response, receiveId);
342
+ return toFeishuSendResult(response, receiveId, resolveFeishuReceiptKind(msgType));
352
343
  }
353
344
  /**
354
345
  * Helper to detect file type from extension
@@ -432,51 +423,47 @@ function isLikelyTranscodableAudio(params) {
432
423
  return FEISHU_TRANSCODABLE_AUDIO_EXTS.has(ext) || mediaKindFromMime(contentType) === "audio";
433
424
  }
434
425
  async function transcodeToFeishuVoiceOpus(params) {
435
- const tempRoot = resolvePreferredOpenClawTmpDir();
436
- await fs.promises.mkdir(tempRoot, {
437
- recursive: true,
438
- mode: 448
439
- });
440
- const tempDir = await fs.promises.mkdtemp(path.join(tempRoot, "feishu-voice-"));
441
- try {
426
+ return await withTempWorkspace({
427
+ rootDir: resolvePreferredOpenClawTmpDir(),
428
+ prefix: "feishu-voice-"
429
+ }, async (workspace) => {
442
430
  const ext = normalizeLowercaseStringOrEmpty(path.extname(params.fileName));
443
431
  const inputExt = ext && ext.length <= 12 ? ext : ".audio";
444
- const inputPath = path.join(tempDir, `input${inputExt}`);
445
- const outputPath = path.join(tempDir, FEISHU_VOICE_FILE_NAME);
446
- await fs.promises.writeFile(inputPath, params.buffer, { mode: 384 });
447
- await runFfmpeg([
448
- "-hide_banner",
449
- "-loglevel",
450
- "error",
451
- "-y",
452
- "-i",
453
- inputPath,
454
- "-vn",
455
- "-sn",
456
- "-dn",
457
- "-t",
458
- String(MEDIA_FFMPEG_MAX_AUDIO_DURATION_SECS),
459
- "-ar",
460
- String(FEISHU_VOICE_SAMPLE_RATE_HZ),
461
- "-ac",
462
- "1",
463
- "-c:a",
464
- "libopus",
465
- "-b:a",
466
- FEISHU_VOICE_BITRATE,
467
- outputPath
468
- ]);
432
+ const inputPath = await workspace.write(`input${inputExt}`, params.buffer);
433
+ await writeExternalFileWithinRoot({
434
+ rootDir: workspace.dir,
435
+ path: FEISHU_VOICE_FILE_NAME,
436
+ write: async (outputPath) => {
437
+ await runFfmpeg([
438
+ "-hide_banner",
439
+ "-loglevel",
440
+ "error",
441
+ "-y",
442
+ "-i",
443
+ inputPath,
444
+ "-vn",
445
+ "-sn",
446
+ "-dn",
447
+ "-t",
448
+ String(MEDIA_FFMPEG_MAX_AUDIO_DURATION_SECS),
449
+ "-ar",
450
+ String(FEISHU_VOICE_SAMPLE_RATE_HZ),
451
+ "-ac",
452
+ "1",
453
+ "-c:a",
454
+ "libopus",
455
+ "-b:a",
456
+ FEISHU_VOICE_BITRATE,
457
+ outputPath
458
+ ]);
459
+ }
460
+ });
469
461
  return {
470
- buffer: await fs.promises.readFile(outputPath),
462
+ buffer: await workspace.read(FEISHU_VOICE_FILE_NAME),
471
463
  fileName: FEISHU_VOICE_FILE_NAME,
472
464
  contentType: "audio/ogg"
473
465
  };
474
- } finally {
475
- await fs.promises.rm(tempDir, {
476
- recursive: true,
477
- force: true
478
- });
479
- }
466
+ });
480
467
  }
481
468
  async function prepareFeishuVoiceMedia(params) {
482
469
  if (isFeishuNativeVoiceAudio(params)) return params;
@@ -845,7 +832,7 @@ async function sendFallbackDirect(client, params, errorPrefix) {
845
832
  }
846
833
  }), errorPrefix, { includeNestedErrorLogId: true });
847
834
  assertFeishuMessageApiSuccess(response, errorPrefix);
848
- return toFeishuSendResult(response, params.receiveId);
835
+ return toFeishuSendResult(response, params.receiveId, resolveFeishuReceiptKind(params.msgType));
849
836
  }
850
837
  async function sendReplyOrFallbackDirect(client, params) {
851
838
  if (!params.replyToMessageId) return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
@@ -870,7 +857,7 @@ async function sendReplyOrFallbackDirect(client, params) {
870
857
  return sendFallbackDirect(client, params.directParams, params.directErrorPrefix);
871
858
  }
872
859
  assertFeishuMessageApiSuccess(response, params.replyErrorPrefix);
873
- return toFeishuSendResult(response, params.directParams.receiveId);
860
+ return toFeishuSendResult(response, params.directParams.receiveId, resolveFeishuReceiptKind(params.msgType));
874
861
  }
875
862
  function normalizeCardTemplateVariable(value) {
876
863
  if (typeof value === "string") return value;
@@ -1215,4 +1202,4 @@ async function sendMarkdownCardFeishu(params) {
1215
1202
  });
1216
1203
  }
1217
1204
  //#endregion
1218
- export { shouldSuppressFeishuTextForVoiceMedia as _, sendCardFeishu as a, sendStructuredCardFeishu as c, extractMentionTargets as d, isFeishuBroadcastMention as f, sendMediaFeishu as g, downloadMessageResourceFeishu as h, resolveFeishuCardTemplate as i, parsePostContent as l, isFeishuGroupChatType as m, getMessageFeishu as n, sendMarkdownCardFeishu as o, isMentionForwardRequest as p, listFeishuThreadMessages as r, sendMessageFeishu as s, editMessageFeishu as t, buildMentionedCardContent as u, normalizeFeishuExternalKey as v };
1205
+ export { normalizeFeishuExternalKey as _, sendCardFeishu as a, sendStructuredCardFeishu as c, isFeishuBroadcastMention as d, isMentionForwardRequest as f, shouldSuppressFeishuTextForVoiceMedia as g, sendMediaFeishu as h, resolveFeishuCardTemplate as i, parsePostContent as l, downloadMessageResourceFeishu as m, getMessageFeishu as n, sendMarkdownCardFeishu as o, isFeishuGroupChatType as p, listFeishuThreadMessages as r, sendMessageFeishu as s, editMessageFeishu as t, extractMentionTargets as u };
@@ -1,4 +1,5 @@
1
1
  import { f as isRecord } from "./accounts-Ba3-WP1z.js";
2
+ import { createMessageReceiptFromOutboundResults } from "openclaw/plugin-sdk/channel-message";
2
3
  //#region extensions/feishu/src/card-interaction.ts
3
4
  const FEISHU_CARD_INTERACTION_VERSION = "ocf1";
4
5
  function isInteractionKind(value) {
@@ -93,4 +94,47 @@ function decodeFeishuCardAction(params) {
93
94
  };
94
95
  }
95
96
  //#endregion
96
- export { decodeFeishuCardAction as i, buildFeishuCardActionTextFallback as n, createFeishuCardInteractionEnvelope as r, FEISHU_CARD_INTERACTION_VERSION as t };
97
+ //#region extensions/feishu/src/send-result.ts
98
+ function resolveFeishuReceiptKind(msgType) {
99
+ switch (msgType) {
100
+ case "audio": return "voice";
101
+ case "image":
102
+ case "media":
103
+ case "file": return "media";
104
+ case "interactive": return "card";
105
+ case "post":
106
+ case "text": return "text";
107
+ default: return "unknown";
108
+ }
109
+ }
110
+ function createFeishuSendReceipt(params) {
111
+ const messageId = params.messageId?.trim();
112
+ const chatId = params.chatId.trim();
113
+ return createMessageReceiptFromOutboundResults({
114
+ results: messageId ? [{
115
+ channel: "feishu",
116
+ messageId,
117
+ chatId,
118
+ conversationId: chatId
119
+ }] : [],
120
+ ...chatId ? { threadId: chatId } : {},
121
+ kind: params.kind ?? "unknown"
122
+ });
123
+ }
124
+ function assertFeishuMessageApiSuccess(response, errorPrefix) {
125
+ if (response.code !== 0) throw new Error(`${errorPrefix}: ${response.msg || `code ${response.code}`}`);
126
+ }
127
+ function toFeishuSendResult(response, chatId, kind) {
128
+ const messageId = response.data?.message_id ?? "unknown";
129
+ return {
130
+ messageId,
131
+ chatId,
132
+ receipt: createFeishuSendReceipt({
133
+ messageId,
134
+ chatId,
135
+ kind
136
+ })
137
+ };
138
+ }
139
+ //#endregion
140
+ export { FEISHU_CARD_INTERACTION_VERSION as a, decodeFeishuCardAction as c, toFeishuSendResult as i, createFeishuSendReceipt as n, buildFeishuCardActionTextFallback as o, resolveFeishuReceiptKind as r, createFeishuCardInteractionEnvelope as s, assertFeishuMessageApiSuccess as t };
package/dist/setup-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-BegH3cJm.js";
1
+ import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-C5kY2KFE.js";
2
2
  export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/feishu",
3
- "version": "2026.5.7",
3
+ "version": "2026.5.9-beta.1",
4
4
  "description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,14 +9,14 @@
9
9
  "type": "module",
10
10
  "dependencies": {
11
11
  "@larksuiteoapi/node-sdk": "^1.62.1",
12
- "typebox": "1.1.37"
12
+ "typebox": "1.1.38"
13
13
  },
14
14
  "devDependencies": {
15
15
  "@openclaw/plugin-sdk": "workspace:*",
16
16
  "openclaw": "workspace:*"
17
17
  },
18
18
  "peerDependencies": {
19
- "openclaw": ">=2026.5.7"
19
+ "openclaw": ">=2026.5.9-beta.1"
20
20
  },
21
21
  "peerDependenciesMeta": {
22
22
  "openclaw": {
@@ -47,10 +47,10 @@
47
47
  "minHostVersion": ">=2026.4.25"
48
48
  },
49
49
  "compat": {
50
- "pluginApi": ">=2026.5.7"
50
+ "pluginApi": ">=2026.5.9-beta.1"
51
51
  },
52
52
  "build": {
53
- "openclawVersion": "2026.5.7"
53
+ "openclawVersion": "2026.5.9-beta.1"
54
54
  },
55
55
  "release": {
56
56
  "publishToClawHub": true,