@openclaw/feishu 2026.7.2-beta.2 → 2026.7.2-beta.3

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
@@ -1,10 +1,10 @@
1
1
  import { r as listEnabledFeishuAccounts } from "./accounts-BDoGHJDk.js";
2
- import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-X30GQVwc.js";
3
- import { p as parseFeishuMarkdown, u as chunkFeishuMarkdown } from "./send-result-DsqTk27v.js";
2
+ import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-BdnXYU6g.js";
3
+ import { p as parseFeishuMarkdown, u as chunkFeishuMarkdown } from "./send-result-DfE5Fhz6.js";
4
4
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-BeJL-wq7.js";
5
5
  import { r as createFeishuClient, s as resolveConfiguredHttpTimeoutMs } from "./client-87BmeMpj.js";
6
6
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
7
- import { a as toolExecutionErrorResult, f as registerFeishuChatTools, g as resolveToolsConfig, h as resolveFeishuToolAccount, m as resolveAnyEnabledFeishuToolsConfig, n as registerFeishuDriveTools, o as unknownToolActionResult, p as createFeishuToolClient } from "./drive-B4E8OXZ0.js";
7
+ import { a as toolExecutionErrorResult, f as registerFeishuChatTools, g as resolveToolsConfig, h as resolveFeishuToolAccount, m as resolveAnyEnabledFeishuToolsConfig, n as registerFeishuDriveTools, o as unknownToolActionResult, p as createFeishuToolClient } from "./drive-BHv8WW9i.js";
8
8
  import { n as getFeishuThreadBindingManager, r as testing, t as createFeishuThreadBindingManager } from "./thread-bindings-V0bwk0A1.js";
9
9
  import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-BKTOxB-T.js";
10
10
  import { optionalPositiveIntegerSchema } from "openclaw/plugin-sdk/channel-actions";
@@ -1,10 +1,10 @@
1
1
  import { a as resolveDefaultFeishuAccountId, d as isRecord$1, i as listFeishuAccountIds, n as inspectFeishuCredentials, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-BDoGHJDk.js";
2
2
  import { i as resolveReceiveIdType, n as looksLikeFeishuId, r as normalizeFeishuTarget } from "./targets-BUjQ1TcA.js";
3
- import { A as resolveFeishuChatType, D as resolveFeishuGroupToolPolicy, N as createFeishuCardInteractionEnvelope, _ as canEnumerateAllFeishuPeers, a as readNativeFeishuCardJson, b as resolveFeishuChatReadPreliminaryAuthorization, g as canEnumerateAllFeishuGroups, h as authorizeFeishuChatMemberRead, k as normalizeFeishuChatType, m as assertFeishuChatReadAllowed, n as createFeishuSendReceipt, u as chunkFeishuMarkdown, v as isFeishuGroupReadAllowed, w as resolveFeishuGroupConfig, y as isFeishuGroupReadEnabled } from "./send-result-DsqTk27v.js";
3
+ import { A as resolveFeishuChatType, D as resolveFeishuGroupToolPolicy, N as createFeishuCardInteractionEnvelope, _ as canEnumerateAllFeishuPeers, a as readNativeFeishuCardJson, b as resolveFeishuChatReadPreliminaryAuthorization, g as canEnumerateAllFeishuGroups, h as authorizeFeishuChatMemberRead, k as normalizeFeishuChatType, m as assertFeishuChatReadAllowed, n as createFeishuSendReceipt, u as chunkFeishuMarkdown, v as isFeishuGroupReadAllowed, w as resolveFeishuGroupConfig, y as isFeishuGroupReadEnabled } from "./send-result-DfE5Fhz6.js";
4
4
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, o as resolveConfiguredFeishuGroupSessionScope, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-BeJL-wq7.js";
5
5
  import { n as normalizeCompatibilityConfig, t as legacyConfigRules } from "./doctor-contract-DXH5hux1.js";
6
6
  import { t as messageActionTargetAliases } from "./security-audit-BIeA3W3Q.js";
7
- import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DnlMcrn5.js";
7
+ import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-BCpDLdg9.js";
8
8
  import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BIHeF-S_.js";
9
9
  import { t as resolveFeishuSessionConversation } from "./session-conversation-BksWrfzm.js";
10
10
  import { createLazyRuntimeModule, createLazyRuntimeNamedExport } from "openclaw/plugin-sdk/lazy-runtime";
@@ -18,12 +18,12 @@ import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing
18
18
  import { createAllowlistProviderGroupPolicyWarningCollector, projectConfigAccountIdWarningCollector } from "openclaw/plugin-sdk/channel-policy";
19
19
  import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-runtime";
20
20
  import { applyDirectoryQueryAndLimit, createChannelDirectoryAdapter, createRuntimeDirectoryLiveAdapter, listDirectoryGroupEntriesFromMapKeysAndAllowFrom, listDirectoryUserEntriesFromAllowFrom, listDirectoryUserEntriesFromAllowFromAndMapKeys } from "openclaw/plugin-sdk/directory-runtime";
21
- import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationChartFallbackText, renderMessagePresentationFallbackText, renderMessagePresentationTableFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
21
+ import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationChartFallbackText, renderMessagePresentationFallbackText, renderMessagePresentationTableFallbackText, resolveLegacyInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
22
22
  import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
23
23
  import { buildProbeChannelStatusSummary, createComputedAccountStatusAdapter, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/status-helpers";
24
24
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
25
25
  import { sanitizeAssistantVisibleText } from "openclaw/plugin-sdk/text-chunking";
26
- import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2 } from "openclaw/plugin-sdk/account-resolution";
26
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$3 } from "openclaw/plugin-sdk/account-resolution";
27
27
  import { createChannelApprovalAuth } from "openclaw/plugin-sdk/approval-auth-runtime";
28
28
  import { PAIRING_APPROVED_MESSAGE } from "openclaw/plugin-sdk/channel-status";
29
29
  import { normalizeAccountId as normalizeAccountId$1 } from "openclaw/plugin-sdk/account-id";
@@ -36,7 +36,7 @@ import path from "node:path";
36
36
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
37
37
  import { deleteSessionEntry, isValidAgentHarnessSessionStoreEntry, listSessionEntries, loadTranscriptEventsSync, parseSqliteSessionFileMarker, resolveSessionStoreBackupPaths, resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
38
38
  import { resolveStateDir } from "openclaw/plugin-sdk/state-paths";
39
- import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$1, createSetupTranslator, formatDocsLink, hasConfiguredSecretInput as hasConfiguredSecretInput$1, mergeAllowFromEntries, patchTopLevelChannelConfigSection, promptSingleChannelSecretInput, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
39
+ import { DEFAULT_ACCOUNT_ID as DEFAULT_ACCOUNT_ID$2, createSetupTranslator, formatDocsLink, hasConfiguredSecretInput as hasConfiguredSecretInput$1, mergeAllowFromEntries, patchTopLevelChannelConfigSection, promptSingleChannelSecretInput, setSetupChannelEnabled, splitSetupEntries } from "openclaw/plugin-sdk/setup";
40
40
  //#region extensions/feishu/src/approval-auth.ts
41
41
  function normalizeFeishuApproverId(value) {
42
42
  const trimmed = normalizeOptionalLowercaseString(normalizeFeishuTarget(String(value)));
@@ -221,6 +221,8 @@ const FeishuSharedConfigShape = {
221
221
  reactionNotifications: ReactionNotificationModeSchema,
222
222
  typingIndicator: z.boolean().optional(),
223
223
  resolveSenderNames: z.boolean().optional(),
224
+ allowBots: z.boolean().optional(),
225
+ vcAutoJoin: z.boolean().optional(),
224
226
  tts: TtsOverrideSchema
225
227
  };
226
228
  /**
@@ -1217,7 +1219,7 @@ function setFeishuNamedAccountEnabled$1(cfg, accountId, enabled) {
1217
1219
  const feishuSetupAdapter = {
1218
1220
  resolveAccountId: ({ cfg, accountId }) => accountId?.trim() || resolveDefaultFeishuAccountId(cfg),
1219
1221
  applyAccountConfig: ({ cfg, accountId }) => {
1220
- if (!accountId || accountId === DEFAULT_ACCOUNT_ID$1) return {
1222
+ if (!accountId || accountId === DEFAULT_ACCOUNT_ID$2) return {
1221
1223
  ...cfg,
1222
1224
  channels: {
1223
1225
  ...cfg.channels,
@@ -1269,7 +1271,7 @@ function formatFeishuStatusLine(status) {
1269
1271
  */
1270
1272
  function patchFeishuConfig(cfg, accountId, patch) {
1271
1273
  const feishuCfg = cfg.channels?.feishu;
1272
- if (accountId === DEFAULT_ACCOUNT_ID$1) return patchTopLevelChannelConfigSection({
1274
+ if (accountId === DEFAULT_ACCOUNT_ID$2) return patchTopLevelChannelConfigSection({
1273
1275
  cfg,
1274
1276
  channel,
1275
1277
  enabled: true,
@@ -1293,7 +1295,7 @@ function patchFeishuConfig(cfg, accountId, patch) {
1293
1295
  async function promptFeishuAllowFrom(params) {
1294
1296
  const feishuCfg = params.cfg.channels?.feishu;
1295
1297
  const resolvedAccountId = params.accountId ?? resolveDefaultFeishuAccountId(params.cfg);
1296
- const existingAllowFrom = (resolvedAccountId !== DEFAULT_ACCOUNT_ID$1 ? feishuCfg?.accounts?.[resolvedAccountId] : void 0)?.allowFrom ?? feishuCfg?.allowFrom ?? [];
1298
+ const existingAllowFrom = (resolvedAccountId !== DEFAULT_ACCOUNT_ID$2 ? feishuCfg?.accounts?.[resolvedAccountId] : void 0)?.allowFrom ?? feishuCfg?.allowFrom ?? [];
1297
1299
  await params.prompter.note([
1298
1300
  t("wizard.feishu.allowlistIntro"),
1299
1301
  t("wizard.feishu.allowlistFindUser"),
@@ -1333,7 +1335,7 @@ const feishuDmPolicy = {
1333
1335
  allowFromKey: "channels.feishu.allowFrom",
1334
1336
  resolveConfigKeys: (_cfg, accountId) => {
1335
1337
  const resolvedAccountId = accountId ?? resolveDefaultFeishuAccountId(_cfg);
1336
- return resolvedAccountId !== DEFAULT_ACCOUNT_ID$1 ? {
1338
+ return resolvedAccountId !== DEFAULT_ACCOUNT_ID$2 ? {
1337
1339
  policyKey: `channels.feishu.accounts.${resolvedAccountId}.dmPolicy`,
1338
1340
  allowFromKey: `channels.feishu.accounts.${resolvedAccountId}.allowFrom`
1339
1341
  } : {
@@ -1344,7 +1346,7 @@ const feishuDmPolicy = {
1344
1346
  getCurrent: (cfg, accountId) => {
1345
1347
  const feishuCfg = cfg.channels?.feishu;
1346
1348
  const resolvedAccountId = accountId ?? resolveDefaultFeishuAccountId(cfg);
1347
- if (resolvedAccountId !== DEFAULT_ACCOUNT_ID$1) {
1349
+ if (resolvedAccountId !== DEFAULT_ACCOUNT_ID$2) {
1348
1350
  const account = feishuCfg?.accounts?.[resolvedAccountId];
1349
1351
  if (account?.dmPolicy) return account.dmPolicy;
1350
1352
  }
@@ -1666,7 +1668,7 @@ const meta = {
1666
1668
  order: 70,
1667
1669
  preferSessionLookupForAnnounceTarget: true
1668
1670
  };
1669
- const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-By2uqa3Q.js"), "feishuChannelRuntime");
1671
+ const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-CVIzo2dV.js"), "feishuChannelRuntime");
1670
1672
  function toFeishuMessageSendResult(result, kind) {
1671
1673
  const receipt = result.receipt ?? createFeishuSendReceipt({
1672
1674
  messageId: result.messageId,
@@ -2148,7 +2150,7 @@ const feishuPlugin = createChatChannelPlugin({
2148
2150
  config: {
2149
2151
  ...feishuConfigAdapter,
2150
2152
  setAccountEnabled: ({ cfg, accountId, enabled }) => {
2151
- if (accountId === DEFAULT_ACCOUNT_ID$2) return {
2153
+ if (accountId === DEFAULT_ACCOUNT_ID$3) return {
2152
2154
  ...cfg,
2153
2155
  channels: {
2154
2156
  ...cfg.channels,
@@ -2161,7 +2163,7 @@ const feishuPlugin = createChatChannelPlugin({
2161
2163
  return setFeishuNamedAccountEnabled(cfg, accountId, enabled);
2162
2164
  },
2163
2165
  deleteAccount: ({ cfg, accountId }) => {
2164
- if (accountId === DEFAULT_ACCOUNT_ID$2) {
2166
+ if (accountId === DEFAULT_ACCOUNT_ID$3) {
2165
2167
  const next = { ...cfg };
2166
2168
  const nextChannels = { ...cfg.channels };
2167
2169
  delete nextChannels.feishu;
@@ -2217,14 +2219,14 @@ const feishuPlugin = createChatChannelPlugin({
2217
2219
  if (ctx.action === "thread-reply" && !replyToMessageId) throw new Error("Feishu thread-reply requires messageId.");
2218
2220
  const text = readFirstString(ctx.params, ["text", "message"]);
2219
2221
  const textCard = readNativeFeishuCardJson(text, { responsePrefix: resolveFeishuMessageActionResponsePrefix(ctx) });
2220
- const interactive = normalizeInteractiveReply(ctx.params.interactive);
2221
- const presentation = normalizeMessagePresentation(ctx.params.presentation) ?? (interactive ? interactiveReplyToPresentation(interactive) : void 0);
2222
+ const interactive = normalizeLegacyInteractiveReply(ctx.params.interactive);
2223
+ const presentation = normalizeMessagePresentation(ctx.params.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
2222
2224
  const mediaUrl = readFeishuMediaParam(ctx.params);
2223
2225
  const audioAsVoice = readBooleanParam(ctx.params, ["asVoice", "audioAsVoice"]);
2224
2226
  if (textCard && !presentation) assertFeishuCardWithinEnvelope(textCard, "Feishu native card");
2225
2227
  const generatedCard = presentation ? buildFeishuPresentationCard({
2226
2228
  presentation,
2227
- fallbackText: textCard ? void 0 : resolveInteractiveTextFallback({
2229
+ fallbackText: textCard ? void 0 : resolveLegacyInteractiveTextFallback({
2228
2230
  text,
2229
2231
  interactive
2230
2232
  })
@@ -2739,7 +2741,7 @@ const feishuPlugin = createChatChannelPlugin({
2739
2741
  })
2740
2742
  }),
2741
2743
  status: createComputedAccountStatusAdapter({
2742
- defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID$2, { port: null }),
2744
+ defaultRuntime: createDefaultChannelRuntimeState(DEFAULT_ACCOUNT_ID$3, { port: null }),
2743
2745
  buildChannelSummary: ({ snapshot }) => buildProbeChannelStatusSummary(snapshot, { port: snapshot.port ?? null }),
2744
2746
  probeAccount: async ({ account }) => await (await loadFeishuChannelRuntime()).probeFeishu(account),
2745
2747
  resolveAccountSnapshot: ({ account, runtime }) => ({
@@ -2755,7 +2757,7 @@ const feishuPlugin = createChatChannelPlugin({
2755
2757
  })
2756
2758
  }),
2757
2759
  gateway: { startAccount: async (ctx) => {
2758
- const { monitorFeishuProvider } = await import("./monitor-CHl0bWzb.js");
2760
+ const { monitorFeishuProvider } = await import("./monitor-BVQf7-Bl.js");
2759
2761
  const account = resolveFeishuRuntimeAccount({
2760
2762
  cfg: ctx.cfg,
2761
2763
  accountId: ctx.accountId
@@ -1,2 +1,2 @@
1
- import { t as feishuPlugin } from "./channel-X30GQVwc.js";
1
+ import { t as feishuPlugin } from "./channel-BdnXYU6g.js";
2
2
  export { feishuPlugin };
@@ -1,19 +1,19 @@
1
1
  import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, v as parseFeishuCommentTarget } from "./accounts-BDoGHJDk.js";
2
- import { c as isFeishuCardWithinEnvelope, l as listFeishuDirectoryGroups, o as assertFeishuCardWithinEnvelope, s as buildFeishuPresentationCardElements, u as listFeishuDirectoryPeers } from "./channel-X30GQVwc.js";
3
- import { a as readNativeFeishuCardJson, d as chunkFeishuPostMarkdown, f as materializeFeishuPostMarkdownSoftBreaks, o as resolveFeishuCardTemplate, s as sanitizeNativeFeishuCard, u as chunkFeishuMarkdown } from "./send-result-DsqTk27v.js";
2
+ import { c as isFeishuCardWithinEnvelope, l as listFeishuDirectoryGroups, o as assertFeishuCardWithinEnvelope, s as buildFeishuPresentationCardElements, u as listFeishuDirectoryPeers } from "./channel-BdnXYU6g.js";
3
+ import { a as readNativeFeishuCardJson, d as chunkFeishuPostMarkdown, f as materializeFeishuPostMarkdownSoftBreaks, o as resolveFeishuCardTemplate, s as sanitizeNativeFeishuCard, u as chunkFeishuMarkdown } from "./send-result-DfE5Fhz6.js";
4
4
  import { r as createFeishuClient } from "./client-87BmeMpj.js";
5
- import { c as buildFeishuDirectChatMembers, d as getFeishuMemberInfo, l as getChatInfo, r as cleanupAmbientCommentTypingReaction, s as assertFeishuChatMember, t as deliverCommentThreadText, u as getChatMembers } from "./drive-B4E8OXZ0.js";
6
- import { a as sendMarkdownCardFeishu, h as shouldSuppressFeishuTextForVoiceMedia, i as sendCardFeishu, m as sendMediaFeishu, n as getMessageFeishu, o as sendMessageFeishu, s as sendStructuredCardFeishu, t as editMessageFeishu, v as resolveFeishuIdentityHeaderTitle } from "./send-DrWM_Ilf.js";
5
+ import { c as buildFeishuDirectChatMembers, d as getFeishuMemberInfo, l as getChatInfo, r as cleanupAmbientCommentTypingReaction, s as assertFeishuChatMember, t as deliverCommentThreadText, u as getChatMembers } from "./drive-BHv8WW9i.js";
6
+ import { _ as buildFeishuMediaFallbackText, a as sendMarkdownCardFeishu, h as shouldSuppressFeishuTextForVoiceMedia, i as sendCardFeishu, m as sendMediaFeishu, n as getMessageFeishu, o as sendMessageFeishu, s as sendStructuredCardFeishu, t as editMessageFeishu, y as resolveFeishuIdentityHeaderTitle } from "./send-DcrXbqqA.js";
7
7
  import { t as probeFeishu } from "./probe-BgboTHIn.js";
8
8
  import { createReplyToFanout } from "openclaw/plugin-sdk/channel-outbound";
9
- import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
9
+ import { legacyInteractiveReplyToPresentation, normalizeLegacyInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveLegacyInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
10
10
  import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
11
11
  import { convertMarkdownTables } from "openclaw/plugin-sdk/text-chunking";
12
12
  import path from "node:path";
13
13
  import { resolveChunkMode, resolveTextChunkLimit } from "openclaw/plugin-sdk/reply-chunking";
14
14
  import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
15
15
  import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
16
- import { resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
16
+ import { getReplyPayloadTtsSupplement, resolvePayloadMediaUrls, sendPayloadMediaSequenceAndFinalize, sendTextMediaPayload } from "openclaw/plugin-sdk/reply-payload";
17
17
  import { statRegularFileSync } from "openclaw/plugin-sdk/security-runtime";
18
18
  //#region extensions/feishu/src/directory.ts
19
19
  const MAX_FEISHU_DIRECTORY_PAGES = 100;
@@ -167,14 +167,14 @@ function buildFeishuPayloadCard(params) {
167
167
  }
168
168
  const rawText = params.text ?? params.payload.text;
169
169
  const textCard = readNativeFeishuCardJson(rawText);
170
- const interactive = normalizeInteractiveReply(params.payload.interactive);
171
- const presentation = normalizeMessagePresentation(params.payload.presentation) ?? (interactive ? interactiveReplyToPresentation(interactive) : void 0);
170
+ const interactive = normalizeLegacyInteractiveReply(params.payload.interactive);
171
+ const presentation = normalizeMessagePresentation(params.payload.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
172
172
  if (!presentation && !interactive) {
173
173
  if (!textCard) return;
174
174
  assertFeishuCardWithinEnvelope(textCard, "Feishu native card");
175
175
  return markRenderedFeishuCard(textCard);
176
176
  }
177
- const text = textCard ? void 0 : resolveInteractiveTextFallback({
177
+ const text = textCard ? void 0 : resolveLegacyInteractiveTextFallback({
178
178
  text: rawText,
179
179
  interactive
180
180
  });
@@ -393,6 +393,51 @@ async function sendFeishuFallbackPayload(params) {
393
393
  }
394
394
  return lastResult;
395
395
  }
396
+ async function sendFeishuTtsSupplementPayload(params) {
397
+ const sendMedia = feishuOutbound.sendMedia;
398
+ const sendText = feishuOutbound.sendText;
399
+ if (!sendMedia || !sendText) throw new Error("Feishu TTS supplement delivery is not available.");
400
+ const { normalizedReplyToId } = resolveFeishuReplyMode({
401
+ replyToId: params.ctx.replyToId,
402
+ threadId: params.ctx.threadId
403
+ });
404
+ const nextReplyToId = createReplyToFanout({
405
+ replyToId: normalizedReplyToId,
406
+ replyToIdSource: params.ctx.replyToIdSource,
407
+ replyToMode: params.ctx.replyToMode
408
+ });
409
+ const ctx = {
410
+ ...params.ctx,
411
+ payload: params.payload
412
+ };
413
+ let lastResult;
414
+ if (params.sendVisiblePayload) {
415
+ lastResult = await params.sendVisiblePayload(nextReplyToId());
416
+ await ctx.onDeliveryResult?.(lastResult);
417
+ } else if (params.supplement.visibleTextAlreadyDelivered !== true) {
418
+ const text = params.payload.text?.trim() ? params.payload.text : params.supplement.spokenText;
419
+ for (const chunk of chunkFeishuMarkdown(text, FEISHU_TEXT_CHUNK_LIMIT)) {
420
+ lastResult = await sendText({
421
+ ...ctx,
422
+ text: chunk,
423
+ replyToId: nextReplyToId(),
424
+ onDeliveryResult: void 0
425
+ });
426
+ await ctx.onDeliveryResult?.(lastResult);
427
+ }
428
+ }
429
+ for (const mediaUrl of normalizeStringEntries(resolvePayloadMediaUrls(params.payload))) lastResult = await sendMedia({
430
+ ...ctx,
431
+ text: "",
432
+ mediaUrl,
433
+ replyToId: nextReplyToId(),
434
+ audioAsVoice: params.payload.audioAsVoice ?? ctx.audioAsVoice
435
+ });
436
+ return lastResult ?? {
437
+ channel: "feishu",
438
+ messageId: ""
439
+ };
440
+ }
396
441
  const feishuOutbound = {
397
442
  deliveryMode: "direct",
398
443
  chunker: chunkFeishuMarkdown,
@@ -421,9 +466,10 @@ const feishuOutbound = {
421
466
  renderPresentation: renderFeishuPresentationPayload,
422
467
  sendPayload: async (ctx) => {
423
468
  const { payload, presentationFallback } = consumeFeishuPresentationFallbackMarker(ctx.payload);
469
+ const ttsSupplement = getReplyPayloadTtsSupplement(payload);
424
470
  if (parseFeishuCommentTarget(ctx.to)) {
425
- const interactive = normalizeInteractiveReply(payload.interactive);
426
- const normalizedPresentation = normalizeMessagePresentation(payload.presentation) ?? (interactive ? interactiveReplyToPresentation(interactive) : void 0);
471
+ const interactive = normalizeLegacyInteractiveReply(payload.interactive);
472
+ const normalizedPresentation = normalizeMessagePresentation(payload.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
427
473
  const textCard = readNativeFeishuCardJson(payload.text);
428
474
  const presentationFallbackText = renderMessagePresentationFallbackText({
429
475
  text: textCard ? void 0 : payload.text,
@@ -450,8 +496,13 @@ const feishuOutbound = {
450
496
  identity: ctx.identity
451
497
  });
452
498
  if (!card) {
453
- const interactive = normalizeInteractiveReply(payload.interactive);
454
- const presentation = normalizeMessagePresentation(payload.presentation) ?? (interactive ? interactiveReplyToPresentation(interactive) : void 0);
499
+ if (ttsSupplement) return await sendFeishuTtsSupplementPayload({
500
+ ctx,
501
+ payload,
502
+ supplement: ttsSupplement
503
+ });
504
+ const interactive = normalizeLegacyInteractiveReply(payload.interactive);
505
+ const presentation = normalizeMessagePresentation(payload.presentation) ?? (interactive ? legacyInteractiveReplyToPresentation(interactive) : void 0);
455
506
  return await sendFeishuFallbackPayload({
456
507
  ctx,
457
508
  payload: presentation ? {
@@ -466,6 +517,25 @@ const feishuOutbound = {
466
517
  separateMediaAndText: presentationFallback || presentation !== void 0
467
518
  });
468
519
  }
520
+ if (ttsSupplement) return await sendFeishuTtsSupplementPayload({
521
+ ctx,
522
+ payload,
523
+ supplement: ttsSupplement,
524
+ sendVisiblePayload: async (replyToId) => {
525
+ const { replyToMessageId, replyInThread } = resolveFeishuReplyMode({
526
+ replyToId,
527
+ threadId: ctx.threadId
528
+ });
529
+ return attachChannelToResult("feishu", await sendCardFeishu({
530
+ cfg: ctx.cfg,
531
+ to: ctx.to,
532
+ card,
533
+ replyToMessageId,
534
+ replyInThread,
535
+ accountId: ctx.accountId ?? void 0
536
+ }));
537
+ }
538
+ });
469
539
  const { normalizedReplyToId } = resolveFeishuReplyMode({
470
540
  replyToId: ctx.replyToId,
471
541
  threadId: ctx.threadId
@@ -532,6 +602,14 @@ const feishuOutbound = {
532
602
  });
533
603
  } catch (err) {
534
604
  console.error(`[feishu] local image path auto-send failed:`, err);
605
+ return await sendOutboundText({
606
+ cfg,
607
+ to,
608
+ text: await buildFeishuMediaFallbackText({}),
609
+ accountId: accountId ?? void 0,
610
+ replyToMessageId,
611
+ replyInThread
612
+ });
535
613
  }
536
614
  if (parseFeishuCommentTarget(to)) return await sendOutboundText({
537
615
  cfg,
@@ -589,7 +667,11 @@ const feishuOutbound = {
589
667
  if (parseFeishuCommentTarget(to)) return await sendOutboundText({
590
668
  cfg,
591
669
  to,
592
- text: [text?.trim(), mediaUrl?.trim()].filter(Boolean).join("\n\n") || mediaUrl || text || "",
670
+ text: mediaUrl?.trim() ? await buildFeishuMediaFallbackText({
671
+ text,
672
+ mediaUrl,
673
+ mediaLinkStyle: "plain"
674
+ }) : text?.trim() ?? "",
593
675
  accountId: accountId ?? void 0,
594
676
  replyToMessageId,
595
677
  replyInThread
@@ -632,7 +714,10 @@ const feishuOutbound = {
632
714
  const fallbackResult = await sendOutboundText({
633
715
  cfg,
634
716
  to,
635
- text: [textSent ? void 0 : text?.trim(), `📎 ${mediaUrl}`].filter(Boolean).join("\n\n"),
717
+ text: await buildFeishuMediaFallbackText({
718
+ text: textSent ? void 0 : text,
719
+ mediaUrl
720
+ }),
636
721
  accountId: accountId ?? void 0,
637
722
  replyToMessageId,
638
723
  replyInThread
@@ -1,5 +1,5 @@
1
1
  import { c as encodeQuery, d as isRecord$1, i as listFeishuAccountIds, l as extractReplyText, m as readString, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount, u as formatFeishuApiError, v as parseFeishuCommentTarget } from "./accounts-BDoGHJDk.js";
2
- import { A as resolveFeishuChatType, b as resolveFeishuChatReadPreliminaryAuthorization, h as authorizeFeishuChatMemberRead, m as assertFeishuChatReadAllowed } from "./send-result-DsqTk27v.js";
2
+ import { A as resolveFeishuChatType, b as resolveFeishuChatReadPreliminaryAuthorization, h as authorizeFeishuChatMemberRead, m as assertFeishuChatReadAllowed } from "./send-result-DfE5Fhz6.js";
3
3
  import { r as createFeishuClient } from "./client-87BmeMpj.js";
4
4
  import { optionalPositiveIntegerSchema } from "openclaw/plugin-sdk/channel-actions";
5
5
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
@@ -2,7 +2,7 @@ import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from
2
2
  import { t as fetchBotIdentityForMonitor } from "./monitor.startup-Cy8NPGAX.js";
3
3
  import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
4
4
  //#region extensions/feishu/src/monitor.ts
5
- const loadMonitorAccountRuntime = createLazyRuntimeModule(() => import("./monitor.account-BSRV2hIF.js"));
5
+ const loadMonitorAccountRuntime = createLazyRuntimeModule(() => import("./monitor.account-Blbf2T6J.js"));
6
6
  async function monitorFeishuProvider(opts = {}) {
7
7
  const cfg = opts.config;
8
8
  if (!cfg) throw new Error("Config is required for Feishu monitor");