@openclaw/feishu 2026.5.24-beta.2 → 2026.5.26-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.
@@ -1,2 +1,2 @@
1
- import { t as feishuPlugin } from "./channel-Br99IozO.js";
1
+ import { t as feishuPlugin } from "./channel-DavfT_AA.js";
2
2
  export { feishuPlugin };
@@ -1,11 +1,11 @@
1
- import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-CRcvqpsl.js";
2
- import { _ as listFeishuDirectoryPeers, g as listFeishuDirectoryGroups, y as createFeishuCardInteractionEnvelope } from "./channel-Br99IozO.js";
1
+ import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-CXnY5H8g.js";
2
+ import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-DavfT_AA.js";
3
3
  import { r as createFeishuClient } from "./client-BnH2fRL2.js";
4
- import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-DMbtRzY9.js";
4
+ import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-DwgWWkJi.js";
5
5
  import { chunkTextForOutbound } from "./runtime-api.js";
6
- 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-DxNatQGH.js";
6
+ 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-DQClIwTI.js";
7
7
  import { t as probeFeishu } from "./probe-Da81t6a5.js";
8
- import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
8
+ import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
10
10
  import path from "node:path";
11
11
  import { attachChannelToResult, createAttachedChannelResultAdapter } from "openclaw/plugin-sdk/channel-send-result";
@@ -102,8 +102,12 @@ function normalizePossibleLocalImagePath(text) {
102
102
  function shouldUseCard(text) {
103
103
  return /```[\s\S]*?```/.test(text) || /\|.+\|[\r\n]+\|[-:| ]+\|/.test(text);
104
104
  }
105
- function isRecord$1(value) {
106
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
105
+ function markRenderedFeishuCard(card) {
106
+ Object.defineProperty(card, RENDERED_FEISHU_CARD, {
107
+ value: true,
108
+ enumerable: false
109
+ });
110
+ return card;
107
111
  }
108
112
  function escapeFeishuCardMarkdownText(text) {
109
113
  return text.replace(/[&<>]/g, (char) => {
@@ -116,7 +120,7 @@ function escapeFeishuCardMarkdownText(text) {
116
120
  });
117
121
  }
118
122
  function resolveSafeFeishuButtonUrl(url) {
119
- const trimmed = url?.trim();
123
+ const trimmed = typeof url === "string" ? url.trim() : "";
120
124
  if (!trimmed) return;
121
125
  try {
122
126
  const parsed = new URL(trimmed);
@@ -125,52 +129,66 @@ function resolveSafeFeishuButtonUrl(url) {
125
129
  return;
126
130
  }
127
131
  }
128
- function markRenderedFeishuCard(card) {
129
- Object.defineProperty(card, RENDERED_FEISHU_CARD, {
130
- value: true,
131
- enumerable: false
132
- });
133
- return card;
132
+ function sanitizeNativeFeishuButtonBehavior(behavior) {
133
+ if (!isRecord(behavior)) return;
134
+ if (behavior.type === "open_url") {
135
+ const safeUrl = resolveSafeFeishuButtonUrl(behavior.default_url) ?? resolveSafeFeishuButtonUrl(behavior.url);
136
+ return safeUrl ? {
137
+ type: "open_url",
138
+ default_url: safeUrl
139
+ } : void 0;
140
+ }
141
+ if (behavior.type === "callback" && isRecord(behavior.value) && behavior.value.oc === "ocf1") return {
142
+ type: "callback",
143
+ value: behavior.value
144
+ };
134
145
  }
135
146
  function sanitizeNativeFeishuCardButton(button) {
136
- if (!isRecord$1(button)) return;
137
- const text = isRecord$1(button.text) && typeof button.text.content === "string" ? button.text.content : void 0;
147
+ if (!isRecord(button)) return;
148
+ const text = isRecord(button.text) && typeof button.text.content === "string" ? button.text.content : void 0;
138
149
  if (!text?.trim()) return;
139
- const style = button.type === "danger" ? "danger" : button.type === "primary" ? "primary" : void 0;
140
- const rendered = {
150
+ const style = button.type === "danger" ? "danger" : button.type === "primary" || button.type === "success" ? "primary" : void 0;
151
+ const behaviors = Array.isArray(button.behaviors) ? button.behaviors.map((behavior) => sanitizeNativeFeishuButtonBehavior(behavior)).filter((behavior) => Boolean(behavior)) : [];
152
+ const rootSafeUrl = resolveSafeFeishuButtonUrl(button.url);
153
+ if (rootSafeUrl) behaviors.push({
154
+ type: "open_url",
155
+ default_url: rootSafeUrl
156
+ });
157
+ if (isRecord(button.value) && button.value.oc === "ocf1") behaviors.push({
158
+ type: "callback",
159
+ value: button.value
160
+ });
161
+ if (behaviors.length === 0) return;
162
+ return {
141
163
  tag: "button",
142
164
  text: {
143
165
  tag: "plain_text",
144
166
  content: text
145
167
  },
146
- type: mapFeishuButtonType(style)
168
+ type: style === "danger" ? "danger" : style === "primary" || style === "success" ? "primary" : "default",
169
+ behaviors
147
170
  };
148
- const safeUrl = resolveSafeFeishuButtonUrl(typeof button.url === "string" ? button.url : void 0);
149
- if (safeUrl) rendered.url = safeUrl;
150
- if (isRecord$1(button.value) && button.value.oc === "ocf1") rendered.value = button.value;
151
- return rendered.url || rendered.value ? rendered : void 0;
152
171
  }
153
- function sanitizeNativeFeishuCardElement(element) {
154
- if (!isRecord$1(element) || typeof element.tag !== "string") return;
155
- if (element.tag === "hr") return { tag: "hr" };
156
- if (element.tag === "markdown" && typeof element.content === "string") return {
172
+ function sanitizeNativeFeishuCardElements(element) {
173
+ if (!isRecord(element) || typeof element.tag !== "string") return [];
174
+ if (element.tag === "hr") return [{ tag: "hr" }];
175
+ if (element.tag === "markdown" && typeof element.content === "string") return [{
157
176
  tag: "markdown",
158
177
  content: escapeFeishuCardMarkdownText(element.content)
159
- };
160
- if (element.tag === "action" && Array.isArray(element.actions)) {
161
- const actions = element.actions.map((action) => sanitizeNativeFeishuCardButton(action)).filter((action) => Boolean(action));
162
- return actions.length > 0 ? {
163
- tag: "action",
164
- actions
165
- } : void 0;
178
+ }];
179
+ if (element.tag === "button") {
180
+ const button = sanitizeNativeFeishuCardButton(element);
181
+ return button ? [button] : [];
166
182
  }
183
+ if (element.tag === "action" && Array.isArray(element.actions)) return element.actions.map((action) => sanitizeNativeFeishuCardButton(action)).filter((action) => Boolean(action));
184
+ return [];
167
185
  }
168
186
  function sanitizeNativeFeishuCard(card) {
169
- const body = isRecord$1(card.body) ? card.body : void 0;
170
- const elements = (Array.isArray(body?.elements) ? body.elements : []).map((element) => sanitizeNativeFeishuCardElement(element)).filter((element) => Boolean(element));
187
+ const body = isRecord(card.body) ? card.body : void 0;
188
+ const elements = (Array.isArray(body?.elements) ? body.elements : []).flatMap((element) => sanitizeNativeFeishuCardElements(element)).filter((element) => Boolean(element));
171
189
  if (elements.length === 0) return;
172
- const header = isRecord$1(card.header) ? card.header : void 0;
173
- const title = isRecord$1(header?.title) && typeof header.title.content === "string" ? header.title.content : void 0;
190
+ const header = isRecord(card.header) ? card.header : void 0;
191
+ const title = isRecord(header?.title) && typeof header.title.content === "string" ? header.title.content : void 0;
174
192
  return markRenderedFeishuCard({
175
193
  schema: "2.0",
176
194
  config: { width_mode: "fill" },
@@ -186,61 +204,12 @@ function sanitizeNativeFeishuCard(card) {
186
204
  }
187
205
  function readNativeFeishuCard(payload) {
188
206
  const feishuData = payload.channelData?.feishu;
189
- if (!isRecord$1(feishuData)) return;
207
+ if (!isRecord(feishuData)) return;
190
208
  const card = feishuData.card ?? feishuData.interactiveCard;
191
- if (!isRecord$1(card)) return;
209
+ if (!isRecord(card)) return;
192
210
  if (card[RENDERED_FEISHU_CARD] === true) return card;
193
211
  return sanitizeNativeFeishuCard(card);
194
212
  }
195
- function mapFeishuButtonType(style) {
196
- if (style === "primary" || style === "success") return "primary";
197
- if (style === "danger") return "danger";
198
- return "default";
199
- }
200
- function buildFeishuPayloadButton(button) {
201
- const rendered = {
202
- tag: "button",
203
- text: {
204
- tag: "plain_text",
205
- content: button.label
206
- },
207
- type: mapFeishuButtonType(button.style)
208
- };
209
- if (button.url) {
210
- const safeUrl = resolveSafeFeishuButtonUrl(button.url);
211
- if (safeUrl) rendered.url = safeUrl;
212
- }
213
- if (button.value) rendered.value = createFeishuCardInteractionEnvelope({
214
- k: "quick",
215
- a: "feishu.payload.button",
216
- q: button.value
217
- });
218
- return rendered.url || rendered.value ? rendered : void 0;
219
- }
220
- function buildFeishuCardElementForBlock(block) {
221
- if (block.type === "text") return {
222
- tag: "markdown",
223
- content: escapeFeishuCardMarkdownText(block.text)
224
- };
225
- if (block.type === "context") return {
226
- tag: "markdown",
227
- content: `<font color='grey'>${escapeFeishuCardMarkdownText(block.text)}</font>`
228
- };
229
- if (block.type === "divider") return { tag: "hr" };
230
- if (block.type === "buttons") {
231
- const actions = block.buttons.map((button) => buildFeishuPayloadButton(button)).filter((button) => Boolean(button));
232
- if (actions.length === 0) return;
233
- return {
234
- tag: "action",
235
- actions
236
- };
237
- }
238
- const labels = block.options.map((option) => `- ${option.label}`).join("\n");
239
- return {
240
- tag: "markdown",
241
- content: `${escapeFeishuCardMarkdownText(block.placeholder?.trim() || "Options")}:\n${escapeFeishuCardMarkdownText(labels)}`
242
- };
243
- }
244
213
  function buildFeishuPayloadCard(params) {
245
214
  const nativeCard = readNativeFeishuCard(params.payload);
246
215
  if (nativeCard) return nativeCard;
@@ -251,22 +220,16 @@ function buildFeishuPayloadCard(params) {
251
220
  text: params.text ?? params.payload.text,
252
221
  interactive
253
222
  });
254
- const elements = [];
255
- if (text?.trim()) elements.push({
256
- tag: "markdown",
257
- content: escapeFeishuCardMarkdownText(text)
258
- });
259
- for (const block of presentation?.blocks ?? []) {
260
- const element = buildFeishuCardElementForBlock(block);
261
- if (element) elements.push(element);
262
- }
263
- if (elements.length === 0) elements.push({
223
+ const elements = presentation ? buildFeishuPresentationCardElements({
224
+ presentation,
225
+ fallbackText: text
226
+ }) : [{
264
227
  tag: "markdown",
265
228
  content: renderMessagePresentationFallbackText({
266
229
  text,
267
230
  presentation
268
231
  })
269
- });
232
+ }];
270
233
  const identityTitle = params.identity ? params.identity.emoji ? `${params.identity.emoji} ${params.identity.name ?? ""}`.trim() : params.identity.name ?? "" : "";
271
234
  const title = presentation?.title ?? identityTitle;
272
235
  const template = resolveFeishuCardTemplate(presentation?.tone === "danger" ? "red" : presentation?.tone === "warning" ? "orange" : presentation?.tone === "success" ? "green" : "blue");
@@ -290,7 +253,7 @@ function renderFeishuPresentationPayload({ payload, presentation, ctx }) {
290
253
  identity: ctx.identity
291
254
  });
292
255
  if (!card) return null;
293
- const existingFeishuData = isRecord$1(payload.channelData?.feishu) ? payload.channelData.feishu : void 0;
256
+ const existingFeishuData = isRecord(payload.channelData?.feishu) ? payload.channelData.feishu : void 0;
294
257
  return {
295
258
  ...payload,
296
259
  text: renderMessagePresentationFallbackText({
@@ -442,7 +405,7 @@ const feishuOutbound = {
442
405
  },
443
406
  adapter: feishuOutbound
444
407
  });
445
- const mediaUrls = resolvePayloadMediaUrls(ctx.payload).map((entry) => entry.trim()).filter(Boolean);
408
+ const mediaUrls = normalizeStringEntries(resolvePayloadMediaUrls(ctx.payload));
446
409
  return attachChannelToResult("feishu", await sendPayloadMediaSequenceAndFinalize({
447
410
  text: ctx.payload.text ?? "",
448
411
  mediaUrls,
@@ -1,4 +1,4 @@
1
- import { d as formatFeishuApiError, f as isRecord$1, h as readString, i as listFeishuAccountIds, l as encodeQuery, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount, u as extractReplyText, y as parseFeishuCommentTarget } from "./accounts-CRcvqpsl.js";
1
+ import { d as formatFeishuApiError, f as isRecord$1, h as readString, i as listFeishuAccountIds, l as encodeQuery, o as resolveFeishuAccount, r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount, u as extractReplyText, y as parseFeishuCommentTarget } from "./accounts-CXnY5H8g.js";
2
2
  import { r as createFeishuClient } from "./client-BnH2fRL2.js";
3
3
  import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
@@ -1,9 +1,9 @@
1
- import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CRcvqpsl.js";
1
+ import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-CXnY5H8g.js";
2
2
  import { l as fetchBotIdentityForMonitor } from "./monitor.state-CxrHFQX2.js";
3
3
  //#region extensions/feishu/src/monitor.ts
4
4
  let monitorAccountRuntimePromise;
5
5
  async function loadMonitorAccountRuntime() {
6
- monitorAccountRuntimePromise ??= import("./monitor.account-CbepO5r8.js");
6
+ monitorAccountRuntimePromise ??= import("./monitor.account-CmXHWuwG.js");
7
7
  return await monitorAccountRuntimePromise;
8
8
  }
9
9
  async function monitorFeishuProvider(opts = {}) {
@@ -1,16 +1,17 @@
1
1
  import { t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
2
2
  import { i as resolveReceiveIdType } from "./targets-BUjQ1TcA.js";
3
3
  import { t as createFeishuThreadBindingManager } from "./thread-bindings-D24m3Cjy.js";
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-CRcvqpsl.js";
5
- import { b as decodeFeishuCardAction, d as resolveFeishuDmIngressAccess, f as resolveFeishuGroupConfig, h as resolveFeishuReplyPolicy, l as hasExplicitFeishuGroupConfig, m as resolveFeishuGroupSenderActivationIngressAccess, p as resolveFeishuGroupConversationIngressAccess, u as normalizeFeishuAllowEntry, v as buildFeishuCardActionTextFallback, y as createFeishuCardInteractionEnvelope } from "./channel-Br99IozO.js";
4
+ import { _ as buildFeishuCommentTarget, f as isRecord$1, h as readString, l as encodeQuery, m as parseCommentContentElements, p as normalizeString, s as resolveFeishuRuntimeAccount, u as extractReplyText, v as normalizeCommentFileType } from "./accounts-CXnY5H8g.js";
5
+ import { c as normalizeFeishuAllowEntry, d as resolveFeishuGroupConversationIngressAccess, f as resolveFeishuGroupSenderActivationIngressAccess, l as resolveFeishuDmIngressAccess, p as resolveFeishuReplyPolicy, s as hasExplicitFeishuGroupConfig, u as resolveFeishuGroupConfig } from "./channel-DavfT_AA.js";
6
+ import { c as decodeFeishuCardAction, o as buildFeishuCardActionTextFallback, s as createFeishuCardInteractionEnvelope } from "./send-result-CHvu8Rr7.js";
6
7
  import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
7
8
  import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-BnH2fRL2.js";
8
- import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-DMbtRzY9.js";
9
- import { buildAgentMediaPayload, createReplyPrefixContext, evaluateSupplementalContextVisibility, loadSessionStore, normalizeAgentId as normalizeAgentId$1, resolveChannelContextVisibilityMode, resolveSessionStoreEntry } from "./runtime-api.js";
10
- 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 saveMessageResourceFeishu, n as getMessageFeishu, p as isFeishuGroupChatType, r as listFeishuThreadMessages, s as sendMessageFeishu, u as extractMentionTargets } from "./send-DxNatQGH.js";
9
+ import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-DwgWWkJi.js";
10
+ import { buildAgentMediaPayload, createReplyPrefixContext, evaluateSupplementalContextVisibility, loadSessionStore, normalizeAgentId as normalizeAgentId$2, 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 saveMessageResourceFeishu, n as getMessageFeishu, p as isFeishuGroupChatType, r as listFeishuThreadMessages, s as sendMessageFeishu, u as extractMentionTargets } from "./send-DQClIwTI.js";
11
12
  import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-Da81t6a5.js";
12
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-CxrHFQX2.js";
13
- import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
14
+ import { asBoolean, asNullableRecord, isRecord, normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString, readStringValue, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
14
15
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
15
16
  import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
16
17
  import { createChannelMessageReplyPipeline } from "openclaw/plugin-sdk/channel-message";
@@ -519,15 +520,12 @@ async function warmupDedupFromDisk(namespace, log) {
519
520
  }
520
521
  //#endregion
521
522
  //#region extensions/feishu/src/dedupe-key.ts
522
- function readRecord(value) {
523
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
524
- }
525
523
  function readExternalKey(value) {
526
524
  return normalizeFeishuExternalKey(typeof value === "string" ? value : "");
527
525
  }
528
526
  function parseContentRecord(content) {
529
527
  try {
530
- return readRecord(JSON.parse(content));
528
+ return asNullableRecord(JSON.parse(content));
531
529
  } catch {
532
530
  return null;
533
531
  }
@@ -666,12 +664,12 @@ function resolveUserPath(p) {
666
664
  //#endregion
667
665
  //#region extensions/feishu/src/agent-config.ts
668
666
  const DEFAULT_AGENT_ID = "main";
669
- function normalizeAgentId(value) {
667
+ function normalizeAgentId$1(value) {
670
668
  return (value ?? "").trim().toLowerCase() || DEFAULT_AGENT_ID;
671
669
  }
672
670
  function resolveFeishuConfigReasoningDefault(cfg, agentId) {
673
- const id = normalizeAgentId(agentId);
674
- return cfg.agents?.list?.find((entry) => normalizeAgentId(entry?.id) === id)?.reasoningDefault ?? cfg.agents?.defaults?.reasoningDefault ?? "off";
671
+ const id = normalizeAgentId$1(agentId);
672
+ return cfg.agents?.list?.find((entry) => normalizeAgentId$1(entry?.id) === id)?.reasoningDefault ?? cfg.agents?.defaults?.reasoningDefault ?? "off";
675
673
  }
676
674
  //#endregion
677
675
  //#region extensions/feishu/src/reasoning-preview.ts
@@ -1976,7 +1974,7 @@ async function handleFeishuMessage(params) {
1976
1974
  const dmPolicy = feishuCfg?.dmPolicy ?? "pairing";
1977
1975
  const configAllowFrom = feishuCfg?.allowFrom ?? [];
1978
1976
  const rawBroadcastAgents = isGroup ? resolveBroadcastAgents(cfg, ctx.chatId) : null;
1979
- const broadcastAgents = rawBroadcastAgents ? [...new Set(rawBroadcastAgents.map((id) => normalizeAgentId$1(id)))] : null;
1977
+ const broadcastAgents = rawBroadcastAgents ? uniqueStrings(rawBroadcastAgents.map((id) => normalizeAgentId$2(id))) : null;
1980
1978
  const messageCreateTimeMs = event.message.create_time ? Number.parseInt(event.message.create_time, 10) : Date.now();
1981
1979
  let requireMention = false;
1982
1980
  if (isGroup) {
@@ -2500,12 +2498,12 @@ async function handleFeishuMessage(params) {
2500
2498
  return;
2501
2499
  }
2502
2500
  const strategy = cfg.broadcast?.strategy === "sequential" ? "sequential" : "parallel";
2503
- const activeAgentId = ctx.mentionedBot || !requireMention ? normalizeAgentId$1(route.agentId) : null;
2504
- const agentIds = (cfg.agents?.list ?? []).map((a) => normalizeAgentId$1(a.id));
2501
+ const activeAgentId = ctx.mentionedBot || !requireMention ? normalizeAgentId$2(route.agentId) : null;
2502
+ const agentIds = (cfg.agents?.list ?? []).map((a) => normalizeAgentId$2(a.id));
2505
2503
  const hasKnownAgents = agentIds.length > 0;
2506
2504
  log(`feishu[${account.accountId}]: broadcasting to ${broadcastAgents.length} agents (strategy=${strategy}, active=${activeAgentId ?? "none"})`);
2507
2505
  const dispatchForAgent = async (agentId) => {
2508
- if (hasKnownAgents && !agentIds.includes(normalizeAgentId$1(agentId))) {
2506
+ if (hasKnownAgents && !agentIds.includes(normalizeAgentId$2(agentId))) {
2509
2507
  log(`feishu[${account.accountId}]: broadcast agent ${agentId} not found in agents.list; skipping`);
2510
2508
  return;
2511
2509
  }
@@ -3254,28 +3252,22 @@ function isFeishuRetryableSyntheticEventError(error) {
3254
3252
  }
3255
3253
  //#endregion
3256
3254
  //#region extensions/feishu/src/monitor.bot-menu-handler.ts
3257
- function readString$1(value) {
3258
- return typeof value === "string" ? value : void 0;
3259
- }
3260
3255
  function readStringOrNumber(value) {
3261
3256
  return typeof value === "string" || typeof value === "number" ? value : void 0;
3262
3257
  }
3263
- function isRecord$2(value) {
3264
- return typeof value === "object" && value !== null && !Array.isArray(value);
3265
- }
3266
3258
  function parseFeishuBotMenuEvent(value) {
3267
- if (!isRecord$2(value)) return null;
3259
+ if (!isRecord(value)) return null;
3268
3260
  const operator = value.operator;
3269
- if (operator !== void 0 && !isRecord$2(operator)) return null;
3261
+ if (operator !== void 0 && !isRecord(operator)) return null;
3270
3262
  return {
3271
- event_key: readString$1(value.event_key),
3263
+ event_key: readStringValue(value.event_key),
3272
3264
  timestamp: readStringOrNumber(value.timestamp),
3273
3265
  operator: operator ? {
3274
- operator_name: readString$1(operator.operator_name),
3275
- operator_id: isRecord$2(operator.operator_id) ? {
3276
- open_id: readString$1(operator.operator_id.open_id),
3277
- user_id: readString$1(operator.operator_id.user_id),
3278
- union_id: readString$1(operator.operator_id.union_id)
3266
+ operator_name: readStringValue(operator.operator_name),
3267
+ operator_id: isRecord(operator.operator_id) ? {
3268
+ open_id: readStringValue(operator.operator_id.open_id),
3269
+ user_id: readStringValue(operator.operator_id.user_id),
3270
+ union_id: readStringValue(operator.operator_id.union_id)
3279
3271
  } : void 0
3280
3272
  } : void 0
3281
3273
  };
@@ -3440,9 +3432,6 @@ const FEISHU_COMMENT_REPLY_MISS_RETRY_LIMIT = 6;
3440
3432
  const FEISHU_COMMENT_THREAD_PROMPT_LIMIT = 20;
3441
3433
  const FEISHU_WHOLE_COMMENT_PROMPT_LIMIT = 12;
3442
3434
  const FEISHU_PROMPT_TEXT_LIMIT = 220;
3443
- function readBoolean(value) {
3444
- return typeof value === "boolean" ? value : void 0;
3445
- }
3446
3435
  function safeJsonStringify(value) {
3447
3436
  try {
3448
3437
  return JSON.stringify(value);
@@ -3589,18 +3578,18 @@ async function fetchDriveComments(params) {
3589
3578
  }
3590
3579
  async function requestFeishuOpenApi(params) {
3591
3580
  const formatErrorDetails = (error) => {
3592
- if (!isRecord$3(error)) return typeof error === "string" ? error : JSON.stringify(error);
3593
- const response = isRecord$3(error.response) ? error.response : void 0;
3594
- const responseData = isRecord$3(response?.data) ? response?.data : void 0;
3581
+ if (!isRecord$1(error)) return typeof error === "string" ? error : JSON.stringify(error);
3582
+ const response = isRecord$1(error.response) ? error.response : void 0;
3583
+ const responseData = isRecord$1(response?.data) ? response?.data : void 0;
3595
3584
  return safeJsonStringify({
3596
3585
  message: typeof error.message === "string" ? error.message : typeof error === "string" ? error : JSON.stringify(error),
3597
- code: readString$2(error.code),
3598
- method: readString$2(isRecord$3(error.config) ? error.config.method : void 0),
3599
- url: readString$2(isRecord$3(error.config) ? error.config.url : void 0),
3586
+ code: readString(error.code),
3587
+ method: readString(isRecord$1(error.config) ? error.config.method : void 0),
3588
+ url: readString(isRecord$1(error.config) ? error.config.url : void 0),
3600
3589
  http_status: typeof response?.status === "number" ? response.status : void 0,
3601
- feishu_code: typeof responseData?.code === "number" ? responseData.code : readString$2(responseData?.code),
3602
- feishu_msg: readString$2(responseData?.msg),
3603
- feishu_log_id: readString$2(responseData?.log_id)
3590
+ feishu_code: typeof responseData?.code === "number" ? responseData.code : readString(responseData?.code),
3591
+ feishu_msg: readString(responseData?.msg),
3592
+ feishu_log_id: readString(responseData?.log_id)
3604
3593
  });
3605
3594
  };
3606
3595
  const result = await raceWithTimeoutAndAbort(params.client.request({
@@ -3656,7 +3645,7 @@ async function resolveCommentReplyContext(params) {
3656
3645
  createTime: typeof params.reply.create_time === "number" ? params.reply.create_time : void 0,
3657
3646
  isBotAuthored: typeof userId === "string" && normalizedBotOpenIds.has(userId),
3658
3647
  content: await resolveParsedCommentContent({
3659
- elements: isRecord$3(params.reply.content) ? params.reply.content.elements : void 0,
3648
+ elements: isRecord$1(params.reply.content) ? params.reply.content.elements : void 0,
3660
3649
  botOpenIds: params.botOpenIds,
3661
3650
  currentDocument: params.currentDocument,
3662
3651
  client: params.client,
@@ -3827,7 +3816,7 @@ async function fetchDriveCommentContext(params) {
3827
3816
  const rootWholeReply = comment.reply_list?.replies?.[0];
3828
3817
  const normalizedBotOpenIds = new Set(Array.from(params.botOpenIds ?? []).map((botId) => normalizeString(botId)).filter((botId) => Boolean(botId)));
3829
3818
  const content = await resolveParsedCommentContent({
3830
- elements: isRecord$3(rootWholeReply?.content) ? rootWholeReply.content.elements : void 0,
3819
+ elements: isRecord$1(rootWholeReply?.content) ? rootWholeReply.content.elements : void 0,
3831
3820
  botOpenIds: params.botOpenIds,
3832
3821
  currentDocument,
3833
3822
  client: params.client,
@@ -3943,7 +3932,7 @@ async function resolveDriveCommentEventCore(params) {
3943
3932
  return null;
3944
3933
  }
3945
3934
  const context = await fetchDriveCommentContext({
3946
- client: createClient ? createClient(account ?? { accountId }) : createFeishuClient((await import("./accounts-CRcvqpsl.js").then((n) => n.t)).resolveFeishuAccount({
3935
+ client: createClient ? createClient(account ?? { accountId }) : createFeishuClient((await import("./accounts-CXnY5H8g.js").then((n) => n.t)).resolveFeishuAccount({
3947
3936
  cfg,
3948
3937
  accountId
3949
3938
  })),
@@ -3973,32 +3962,32 @@ async function resolveDriveCommentEventCore(params) {
3973
3962
  };
3974
3963
  }
3975
3964
  function parseFeishuDriveCommentNoticeEventPayload(value) {
3976
- if (!isRecord$3(value) || !isRecord$3(value.notice_meta)) return null;
3965
+ if (!isRecord$1(value) || !isRecord$1(value.notice_meta)) return null;
3977
3966
  const noticeMeta = value.notice_meta;
3978
- const fromUserId = isRecord$3(noticeMeta.from_user_id) ? noticeMeta.from_user_id : void 0;
3979
- const toUserId = isRecord$3(noticeMeta.to_user_id) ? noticeMeta.to_user_id : void 0;
3967
+ const fromUserId = isRecord$1(noticeMeta.from_user_id) ? noticeMeta.from_user_id : void 0;
3968
+ const toUserId = isRecord$1(noticeMeta.to_user_id) ? noticeMeta.to_user_id : void 0;
3980
3969
  return {
3981
- comment_id: readString$2(value.comment_id),
3982
- event_id: readString$2(value.event_id),
3983
- is_mentioned: readBoolean(value.is_mentioned),
3970
+ comment_id: readString(value.comment_id),
3971
+ event_id: readString(value.event_id),
3972
+ is_mentioned: asBoolean(value.is_mentioned),
3984
3973
  notice_meta: {
3985
- file_token: readString$2(noticeMeta.file_token),
3986
- file_type: readString$2(noticeMeta.file_type),
3974
+ file_token: readString(noticeMeta.file_token),
3975
+ file_type: readString(noticeMeta.file_type),
3987
3976
  from_user_id: fromUserId ? {
3988
- open_id: readString$2(fromUserId.open_id),
3989
- user_id: readString$2(fromUserId.user_id),
3990
- union_id: readString$2(fromUserId.union_id)
3977
+ open_id: readString(fromUserId.open_id),
3978
+ user_id: readString(fromUserId.user_id),
3979
+ union_id: readString(fromUserId.union_id)
3991
3980
  } : void 0,
3992
- notice_type: readString$2(noticeMeta.notice_type),
3981
+ notice_type: readString(noticeMeta.notice_type),
3993
3982
  to_user_id: toUserId ? {
3994
- open_id: readString$2(toUserId.open_id),
3995
- user_id: readString$2(toUserId.user_id),
3996
- union_id: readString$2(toUserId.union_id)
3983
+ open_id: readString(toUserId.open_id),
3984
+ user_id: readString(toUserId.user_id),
3985
+ union_id: readString(toUserId.union_id)
3997
3986
  } : void 0
3998
3987
  },
3999
- reply_id: readString$2(value.reply_id),
4000
- timestamp: readString$2(value.timestamp),
4001
- type: readString$2(value.type)
3988
+ reply_id: readString(value.reply_id),
3989
+ timestamp: readString(value.timestamp),
3990
+ type: readString(value.type)
4002
3991
  };
4003
3992
  }
4004
3993
  async function resolveDriveCommentEventTurn(params) {
@@ -4401,27 +4390,21 @@ function createFeishuDriveCommentNoticeHandler(params) {
4401
4390
  }
4402
4391
  //#endregion
4403
4392
  //#region extensions/feishu/src/monitor.message-handler.ts
4404
- function isRecord$1(value) {
4405
- return typeof value === "object" && value !== null && !Array.isArray(value);
4406
- }
4407
- function readString(value) {
4408
- return typeof value === "string" ? value : void 0;
4409
- }
4410
4393
  function normalizeFeishuChatType$1(value) {
4411
4394
  return value === "group" || value === "topic_group" || value === "private" || value === "p2p" ? value : void 0;
4412
4395
  }
4413
4396
  function parseFeishuMessageEventPayload(value) {
4414
- if (!isRecord$1(value)) return null;
4397
+ if (!isRecord(value)) return null;
4415
4398
  const sender = value.sender;
4416
4399
  const message = value.message;
4417
- if (!isRecord$1(sender) || !isRecord$1(message)) return null;
4400
+ if (!isRecord(sender) || !isRecord(message)) return null;
4418
4401
  const senderId = sender.sender_id;
4419
- if (!isRecord$1(senderId)) return null;
4420
- const messageId = readString(message.message_id);
4421
- const chatId = readString(message.chat_id);
4402
+ if (!isRecord(senderId)) return null;
4403
+ const messageId = readStringValue(message.message_id);
4404
+ const chatId = readStringValue(message.chat_id);
4422
4405
  const chatType = normalizeFeishuChatType$1(message.chat_type);
4423
- const messageType = readString(message.message_type);
4424
- const content = readString(message.content);
4406
+ const messageType = readStringValue(message.message_type);
4407
+ const content = readStringValue(message.content);
4425
4408
  if (!messageId || !chatId || !chatType || !messageType || !content) return null;
4426
4409
  return value;
4427
4410
  }
@@ -4897,7 +4880,7 @@ async function resolveReactionSyntheticEvent(params) {
4897
4880
  const senderId = event.user_id?.open_id;
4898
4881
  const senderUserId = event.user_id?.user_id;
4899
4882
  if (!emoji || !messageId || !senderId) return null;
4900
- const { resolveFeishuAccount } = await import("./accounts-CRcvqpsl.js").then((n) => n.t);
4883
+ const { resolveFeishuAccount } = await import("./accounts-CXnY5H8g.js").then((n) => n.t);
4901
4884
  const reactionNotifications = resolveFeishuAccount({
4902
4885
  cfg,
4903
4886
  accountId
@@ -4949,41 +4932,41 @@ function normalizeFeishuChatType(value) {
4949
4932
  return value === "group" || value === "topic_group" || value === "private" || value === "p2p" ? value : void 0;
4950
4933
  }
4951
4934
  function parseFeishuBotAddedEventPayload(value) {
4952
- if (!isRecord$3(value) || !readString$2(value.chat_id) || !isRecord$3(value.operator_id)) return null;
4935
+ if (!isRecord$1(value) || !readString(value.chat_id) || !isRecord$1(value.operator_id)) return null;
4953
4936
  return value;
4954
4937
  }
4955
4938
  function parseFeishuBotRemovedChatId(value) {
4956
- if (!isRecord$3(value)) return null;
4957
- return readString$2(value.chat_id) ?? null;
4939
+ if (!isRecord$1(value)) return null;
4940
+ return readString(value.chat_id) ?? null;
4958
4941
  }
4959
4942
  function firstString(...values) {
4960
4943
  for (const value of values) {
4961
- const trimmed = readString$2(value)?.trim();
4944
+ const trimmed = readString(value)?.trim();
4962
4945
  if (trimmed) return trimmed;
4963
4946
  }
4964
4947
  }
4965
4948
  function readFeishuIdentityField(value, field) {
4966
- if (!isRecord$3(value)) return;
4949
+ if (!isRecord$1(value)) return;
4967
4950
  return firstString(value[field]);
4968
4951
  }
4969
4952
  function parseFeishuCardActionEventPayload(value) {
4970
- if (!isRecord$3(value)) return null;
4971
- const operator = isRecord$3(value.operator) ? value.operator : {};
4953
+ if (!isRecord$1(value)) return null;
4954
+ const operator = isRecord$1(value.operator) ? value.operator : {};
4972
4955
  const action = value.action;
4973
- const context = isRecord$3(value.context) ? value.context : {};
4974
- if (!isRecord$3(action)) return null;
4956
+ const context = isRecord$1(value.context) ? value.context : {};
4957
+ if (!isRecord$1(action)) return null;
4975
4958
  const operatorUserId = operator.user_id;
4976
- const token = readString$2(value.token);
4959
+ const token = readString(value.token);
4977
4960
  const openId = firstString(operator.open_id, readFeishuIdentityField(operatorUserId, "open_id"), value.open_id, context.open_id);
4978
4961
  const userId = firstString(operator.user_id, readFeishuIdentityField(operatorUserId, "user_id"), value.user_id, context.user_id);
4979
4962
  const unionId = firstString(operator.union_id, readFeishuIdentityField(operatorUserId, "union_id"));
4980
- const tag = readString$2(action.tag);
4963
+ const tag = readString(action.tag);
4981
4964
  const actionValue = action.value;
4982
4965
  const openMessageId = firstString(value.open_message_id, context.open_message_id);
4983
4966
  const contextOpenId = firstString(context.open_id, openId);
4984
4967
  const contextUserId = firstString(context.user_id, userId);
4985
4968
  const chatId = firstString(context.chat_id, context.open_chat_id);
4986
- if (!token || !openId || !tag || !isRecord$3(actionValue)) return null;
4969
+ if (!token || !openId || !tag || !isRecord$1(actionValue)) return null;
4987
4970
  return {
4988
4971
  operator: {
4989
4972
  open_id: openId,
@@ -4,10 +4,10 @@ import { createReplyPrefixContext } from "openclaw/plugin-sdk/channel-message";
4
4
  import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
5
5
  import { PAIRING_APPROVED_MESSAGE, buildProbeChannelStatusSummary, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/channel-status";
6
6
  import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
7
+ import { loadSessionStore, resolveSessionStoreEntry } from "openclaw/plugin-sdk/session-store-runtime";
7
8
  import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, createActionGate, createDedupeCache } from "openclaw/plugin-sdk/core";
8
9
  import { buildAgentMediaPayload } from "openclaw/plugin-sdk/agent-media-payload";
9
10
  import { evaluateSupplementalContextVisibility, filterSupplementalContextItems, resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
10
- import { loadSessionStore, resolveSessionStoreEntry } from "openclaw/plugin-sdk/session-store-runtime";
11
11
  import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
12
12
  import { createPersistentDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
13
13
  import { isRequestBodyLimitError, readRequestBodyWithLimit, requestBodyErrorToText } from "openclaw/plugin-sdk/webhook-ingress";