@openclaw/feishu 2026.5.16-beta.3 → 2026.5.16-beta.5

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,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-DUslC3ob.js";
2
2
  import { isRecord, normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
3
- import { DEFAULT_ACCOUNT_ID, createAccountListHelpers, normalizeAccountId, normalizeOptionalAccountId, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
3
+ import { DEFAULT_ACCOUNT_ID, createAccountListHelpers, hasConfiguredAccountValue, normalizeAccountId, normalizeOptionalAccountId, resolveMergedAccountConfig } from "openclaw/plugin-sdk/account-resolution";
4
4
  import { coerceSecretRef } from "openclaw/plugin-sdk/provider-auth";
5
5
  //#region extensions/feishu/src/comment-target.ts
6
6
  const FEISHU_COMMENT_FILE_TYPES = [
@@ -250,7 +250,13 @@ var accounts_exports = /* @__PURE__ */ __exportAll({
250
250
  resolveFeishuCredentials: () => resolveFeishuCredentials,
251
251
  resolveFeishuRuntimeAccount: () => resolveFeishuRuntimeAccount
252
252
  });
253
- const { listAccountIds: listFeishuAccountIds, resolveDefaultAccountId } = createAccountListHelpers("feishu", { allowUnlistedDefaultAccount: true });
253
+ const { listAccountIds: listFeishuAccountIds, resolveDefaultAccountId } = createAccountListHelpers("feishu", {
254
+ allowUnlistedDefaultAccount: true,
255
+ hasImplicitDefaultAccount: (cfg) => {
256
+ const feishu = cfg.channels?.feishu;
257
+ return hasConfiguredAccountValue(feishu?.appId) && hasConfiguredAccountValue(feishu?.appSecret);
258
+ }
259
+ });
254
260
  function formatSecretRefLabel(ref) {
255
261
  return `${ref.source}:${ref.provider}:${ref.id}`;
256
262
  }
package/dist/api.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-Byq1c20x.js";
2
2
  import { n as createFeishuThreadBindingManager, r as getFeishuThreadBindingManager, t as __testing } from "./thread-bindings-D5kDxq_j.js";
3
3
  import { n as handleFeishuSubagentEnded, r as handleFeishuSubagentSpawning, t as handleFeishuSubagentDeliveryTarget } from "./subagent-hooks-BUPKo9Al.js";
4
- import { r as listEnabledFeishuAccounts } from "./accounts-CP4tDW-z.js";
5
- import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-DLhJC9t0.js";
4
+ import { r as listEnabledFeishuAccounts } from "./accounts-QNGhjZeI.js";
5
+ import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-elV7bWCs.js";
6
6
  import { t as getFeishuRuntime } from "./runtime-Cc16UY23.js";
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-Av1h_Lwd.js";
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-CzLQuxes.js";
8
8
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalString, readStringValue } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { existsSync } from "node:fs";
10
10
  import { homedir } from "node:os";
@@ -1469,11 +1469,12 @@ function registerFeishuDocTools(api) {
1469
1469
  }
1470
1470
  //#endregion
1471
1471
  //#region extensions/feishu/src/wiki-schema.ts
1472
+ const WIKI_SPACE_ID_DESCRIPTION = "Knowledge space ID. Treat as an opaque string and keep it quoted; never pass numeric-looking IDs as numbers.";
1472
1473
  const FeishuWikiSchema = Type.Union([
1473
1474
  Type.Object({ action: Type.Literal("spaces") }),
1474
1475
  Type.Object({
1475
1476
  action: Type.Literal("nodes"),
1476
- space_id: Type.String({ description: "Knowledge space ID" }),
1477
+ space_id: Type.String({ description: WIKI_SPACE_ID_DESCRIPTION }),
1477
1478
  parent_node_token: Type.Optional(Type.String({ description: "Parent node token (optional, omit for root)" }))
1478
1479
  }),
1479
1480
  Type.Object({
@@ -1483,11 +1484,11 @@ const FeishuWikiSchema = Type.Union([
1483
1484
  Type.Object({
1484
1485
  action: Type.Literal("search"),
1485
1486
  query: Type.String({ description: "Search query" }),
1486
- space_id: Type.Optional(Type.String({ description: "Limit search to this space (optional)" }))
1487
+ space_id: Type.Optional(Type.String({ description: "Limit search to this knowledge space. Treat as an opaque string and keep it quoted; never pass numeric-looking IDs as numbers." }))
1487
1488
  }),
1488
1489
  Type.Object({
1489
1490
  action: Type.Literal("create"),
1490
- space_id: Type.String({ description: "Knowledge space ID" }),
1491
+ space_id: Type.String({ description: WIKI_SPACE_ID_DESCRIPTION }),
1491
1492
  title: Type.String({ description: "Node title" }),
1492
1493
  obj_type: Type.Optional(Type.Union([
1493
1494
  Type.Literal("docx"),
@@ -1498,14 +1499,14 @@ const FeishuWikiSchema = Type.Union([
1498
1499
  }),
1499
1500
  Type.Object({
1500
1501
  action: Type.Literal("move"),
1501
- space_id: Type.String({ description: "Source knowledge space ID" }),
1502
+ space_id: Type.String({ description: "Source knowledge space ID. Treat as an opaque string and keep it quoted; never pass numeric-looking IDs as numbers." }),
1502
1503
  node_token: Type.String({ description: "Node token to move" }),
1503
- target_space_id: Type.Optional(Type.String({ description: "Target space ID (optional, same space if omitted)" })),
1504
+ target_space_id: Type.Optional(Type.String({ description: "Target knowledge space ID (optional, same space if omitted). Treat as an opaque string and keep it quoted; never pass numeric-looking IDs as numbers." })),
1504
1505
  target_parent_token: Type.Optional(Type.String({ description: "Target parent node token (optional, root if omitted)" }))
1505
1506
  }),
1506
1507
  Type.Object({
1507
1508
  action: Type.Literal("rename"),
1508
- space_id: Type.String({ description: "Knowledge space ID" }),
1509
+ space_id: Type.String({ description: WIKI_SPACE_ID_DESCRIPTION }),
1509
1510
  node_token: Type.String({ description: "Node token to rename" }),
1510
1511
  title: Type.String({ description: "New title" })
1511
1512
  })
@@ -1513,6 +1514,16 @@ const FeishuWikiSchema = Type.Union([
1513
1514
  //#endregion
1514
1515
  //#region extensions/feishu/src/wiki.ts
1515
1516
  const WIKI_ACCESS_HINT = "To grant wiki access: Open wiki space → Settings → Members → Add the bot. See: https://open.feishu.cn/document/server-docs/docs/wiki-v2/wiki-qa#a40ad4ca";
1517
+ function requireWikiSpaceId(value, fieldName) {
1518
+ if (typeof value !== "string") throw new Error(`${fieldName} must be a string. Feishu wiki space IDs are opaque identifiers; pass them quoted to avoid JavaScript number precision loss.`);
1519
+ const trimmed = value.trim();
1520
+ if (!trimmed) throw new Error(`${fieldName} must not be empty.`);
1521
+ return trimmed;
1522
+ }
1523
+ function optionalWikiSpaceId(value, fieldName) {
1524
+ if (value === void 0 || value === null || value === "") return;
1525
+ return requireWikiSpaceId(value, fieldName);
1526
+ }
1516
1527
  async function listSpaces(client) {
1517
1528
  const res = await client.wiki.space.list({});
1518
1529
  if (res.code !== 0) throw new Error(res.msg);
@@ -1623,19 +1634,34 @@ function registerFeishuWikiTools(api) {
1623
1634
  async execute(_toolCallId, params) {
1624
1635
  const p = params;
1625
1636
  try {
1626
- const client = createFeishuToolClient({
1637
+ const createClient = () => createFeishuToolClient({
1627
1638
  api,
1628
1639
  executeParams: p,
1629
1640
  defaultAccountId
1630
1641
  });
1631
1642
  switch (p.action) {
1632
- case "spaces": return jsonToolResult(await listSpaces(client));
1633
- case "nodes": return jsonToolResult(await listNodes(client, p.space_id, p.parent_node_token));
1634
- case "get": return jsonToolResult(await getNode(client, p.token));
1635
- case "search": return jsonToolResult({ error: "Search is not available. Use feishu_wiki with action: 'nodes' to browse or action: 'get' to lookup by token." });
1636
- case "create": return jsonToolResult(await createNode(client, p.space_id, p.title, p.obj_type, p.parent_node_token));
1637
- case "move": return jsonToolResult(await moveNode(client, p.space_id, p.node_token, p.target_space_id, p.target_parent_token));
1638
- case "rename": return jsonToolResult(await renameNode(client, p.space_id, p.node_token, p.title));
1643
+ case "spaces": return jsonToolResult(await listSpaces(createClient()));
1644
+ case "nodes": {
1645
+ const spaceId = requireWikiSpaceId(p.space_id, "space_id");
1646
+ return jsonToolResult(await listNodes(createClient(), spaceId, p.parent_node_token));
1647
+ }
1648
+ case "get": return jsonToolResult(await getNode(createClient(), p.token));
1649
+ case "search":
1650
+ optionalWikiSpaceId(p.space_id, "space_id");
1651
+ createClient();
1652
+ return jsonToolResult({ error: "Search is not available. Use feishu_wiki with action: 'nodes' to browse or action: 'get' to lookup by token." });
1653
+ case "create": {
1654
+ const spaceId = requireWikiSpaceId(p.space_id, "space_id");
1655
+ return jsonToolResult(await createNode(createClient(), spaceId, p.title, p.obj_type, p.parent_node_token));
1656
+ }
1657
+ case "move": {
1658
+ const spaceId = requireWikiSpaceId(p.space_id, "space_id");
1659
+ return jsonToolResult(await moveNode(createClient(), spaceId, p.node_token, optionalWikiSpaceId(p.target_space_id, "target_space_id"), p.target_parent_token));
1660
+ }
1661
+ case "rename": {
1662
+ const spaceId = requireWikiSpaceId(p.space_id, "space_id");
1663
+ return jsonToolResult(await renameNode(createClient(), spaceId, p.node_token, p.title));
1664
+ }
1639
1665
  default: return unknownToolActionResult(p.action);
1640
1666
  }
1641
1667
  } catch (err) {
@@ -1,6 +1,6 @@
1
1
  import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-Byq1c20x.js";
2
2
  import { n as looksLikeFeishuId, r as normalizeFeishuTarget, t as detectIdType } from "./targets-Bb05cFr4.js";
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-CP4tDW-z.js";
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-QNGhjZeI.js";
4
4
  import { t as messageActionTargetAliases } from "./security-audit-BzTLFO6g.js";
5
5
  import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DIpADEx7.js";
6
6
  import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-B6kEakHj.js";
@@ -1188,7 +1188,7 @@ const meta = {
1188
1188
  aliases: ["lark"],
1189
1189
  order: 70
1190
1190
  };
1191
- const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-6Ww4ftMP.js"), "feishuChannelRuntime");
1191
+ const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-B80sZw_-.js"), "feishuChannelRuntime");
1192
1192
  function toFeishuMessageSendResult(result, kind) {
1193
1193
  const receipt = result.receipt ?? createFeishuSendReceipt({
1194
1194
  messageId: result.messageId,
@@ -2031,7 +2031,7 @@ const feishuPlugin = createChatChannelPlugin({
2031
2031
  })
2032
2032
  }),
2033
2033
  gateway: { startAccount: async (ctx) => {
2034
- const { monitorFeishuProvider } = await import("./monitor-BGTm4U2e.js");
2034
+ const { monitorFeishuProvider } = await import("./monitor-DyoC58EE.js");
2035
2035
  const account = resolveFeishuRuntimeAccount({
2036
2036
  cfg: ctx.cfg,
2037
2037
  accountId: ctx.accountId
@@ -2079,7 +2079,20 @@ const feishuPlugin = createChatChannelPlugin({
2079
2079
  buttons: true,
2080
2080
  selects: false,
2081
2081
  context: true,
2082
- divider: true
2082
+ divider: true,
2083
+ limits: {
2084
+ actions: {
2085
+ maxActions: 20,
2086
+ maxActionsPerRow: 5,
2087
+ maxLabelLength: 40,
2088
+ maxValueBytes: 1024
2089
+ },
2090
+ text: {
2091
+ maxLength: 4e3,
2092
+ encoding: "characters",
2093
+ markdownDialect: "markdown"
2094
+ }
2095
+ }
2083
2096
  },
2084
2097
  renderPresentation: async (ctx) => {
2085
2098
  const renderPresentation = (await loadFeishuChannelRuntime()).feishuOutbound.renderPresentation;
@@ -2098,4 +2111,4 @@ const feishuPlugin = createChatChannelPlugin({
2098
2111
  }
2099
2112
  });
2100
2113
  //#endregion
2101
- export { buildFeishuCardActionTextFallback as _, setFeishuNamedAccountEnabled$1 as a, toFeishuSendResult as c, resolveFeishuGroupConfig as d, resolveFeishuGroupConversationIngressAccess as f, listFeishuDirectoryPeers as g, listFeishuDirectoryGroups as h, feishuSetupAdapter as i, hasExplicitFeishuGroupConfig as l, resolveFeishuReplyPolicy as m, feishuSetupWizard as n, assertFeishuMessageApiSuccess as o, resolveFeishuGroupSenderActivationIngressAccess as p, runFeishuLogin as r, resolveFeishuReceiptKind as s, feishuPlugin as t, resolveFeishuDmIngressAccess as u, createFeishuCardInteractionEnvelope as v, decodeFeishuCardAction as y };
2114
+ export { listFeishuDirectoryPeers as _, setFeishuNamedAccountEnabled$1 as a, decodeFeishuCardAction as b, toFeishuSendResult as c, resolveFeishuDmIngressAccess as d, resolveFeishuGroupConfig as f, listFeishuDirectoryGroups as g, resolveFeishuReplyPolicy as h, feishuSetupAdapter as i, hasExplicitFeishuGroupConfig as l, resolveFeishuGroupSenderActivationIngressAccess as m, feishuSetupWizard as n, assertFeishuMessageApiSuccess as o, resolveFeishuGroupConversationIngressAccess as p, runFeishuLogin as r, resolveFeishuReceiptKind as s, feishuPlugin as t, normalizeFeishuAllowEntry as u, buildFeishuCardActionTextFallback as v, createFeishuCardInteractionEnvelope as y };
@@ -1,2 +1,2 @@
1
- import { t as feishuPlugin } from "./channel-DLhJC9t0.js";
1
+ import { t as feishuPlugin } from "./channel-elV7bWCs.js";
2
2
  export { feishuPlugin };
@@ -1,9 +1,9 @@
1
- import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-CP4tDW-z.js";
2
- import { g as listFeishuDirectoryPeers, h as listFeishuDirectoryGroups, v as createFeishuCardInteractionEnvelope } from "./channel-DLhJC9t0.js";
1
+ import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, y as parseFeishuCommentTarget } from "./accounts-QNGhjZeI.js";
2
+ import { _ as listFeishuDirectoryPeers, g as listFeishuDirectoryGroups, y as createFeishuCardInteractionEnvelope } from "./channel-elV7bWCs.js";
3
3
  import { r as createFeishuClient } from "./client-B18oTGHf.js";
4
- import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-Av1h_Lwd.js";
4
+ import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-CzLQuxes.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-Csj0slBG.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-Br5Gy-dU.js";
7
7
  import { t as probeFeishu } from "./probe-DpPNslkb.js";
8
8
  import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
9
9
  import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
@@ -391,7 +391,20 @@ const feishuOutbound = {
391
391
  buttons: true,
392
392
  selects: false,
393
393
  context: true,
394
- divider: true
394
+ divider: true,
395
+ limits: {
396
+ actions: {
397
+ maxActions: 20,
398
+ maxActionsPerRow: 5,
399
+ maxLabelLength: 40,
400
+ maxValueBytes: 1024
401
+ },
402
+ text: {
403
+ maxLength: 4e3,
404
+ encoding: "characters",
405
+ markdownDialect: "markdown"
406
+ }
407
+ }
395
408
  },
396
409
  renderPresentation: renderFeishuPresentationPayload,
397
410
  sendPayload: async (ctx) => {
@@ -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-CP4tDW-z.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-QNGhjZeI.js";
2
2
  import { r as createFeishuClient } from "./client-B18oTGHf.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-CP4tDW-z.js";
1
+ import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-QNGhjZeI.js";
2
2
  import { l as fetchBotIdentityForMonitor } from "./monitor.state-D6ByOM5W.js";
3
3
  //#region extensions/feishu/src/monitor.ts
4
4
  let monitorAccountRuntimePromise;
5
5
  async function loadMonitorAccountRuntime() {
6
- monitorAccountRuntimePromise ??= import("./monitor.account-Cn20lZwr.js");
6
+ monitorAccountRuntimePromise ??= import("./monitor.account-ByWHSzXQ.js");
7
7
  return await monitorAccountRuntimePromise;
8
8
  }
9
9
  async function monitorFeishuProvider(opts = {}) {
@@ -1,17 +1,18 @@
1
1
  import { t as buildFeishuConversationId } from "./conversation-id-Byq1c20x.js";
2
2
  import { i as resolveReceiveIdType } from "./targets-Bb05cFr4.js";
3
3
  import { n as createFeishuThreadBindingManager } from "./thread-bindings-D5kDxq_j.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-CP4tDW-z.js";
5
- import { _ as buildFeishuCardActionTextFallback, d as resolveFeishuGroupConfig, f as resolveFeishuGroupConversationIngressAccess, l as hasExplicitFeishuGroupConfig, m as resolveFeishuReplyPolicy, p as resolveFeishuGroupSenderActivationIngressAccess, u as resolveFeishuDmIngressAccess, v as createFeishuCardInteractionEnvelope, y as decodeFeishuCardAction } from "./channel-DLhJC9t0.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-QNGhjZeI.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-elV7bWCs.js";
6
6
  import { t as getFeishuRuntime } from "./runtime-Cc16UY23.js";
7
7
  import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-B18oTGHf.js";
8
- import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-Av1h_Lwd.js";
8
+ import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-CzLQuxes.js";
9
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-Csj0slBG.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-Br5Gy-dU.js";
11
11
  import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-DpPNslkb.js";
12
12
  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-D6ByOM5W.js";
13
13
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
14
14
  import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
15
+ import { resolveInboundLastRouteSessionKey } from "openclaw/plugin-sdk/routing";
15
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";
@@ -25,7 +26,7 @@ import { createPersistentDedupe } from "openclaw/plugin-sdk/persistent-dedupe";
25
26
  import { applyBasicWebhookRequestGuards, resolveRequestClientIp } from "openclaw/plugin-sdk/webhook-ingress";
26
27
  import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
27
28
  import { resolveSendableOutboundReplyParts, resolveTextChunksWithFallback, sendMediaWithLeadingCaption } from "openclaw/plugin-sdk/reply-payload";
28
- import { safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
29
+ import { resolvePinnedMainDmOwnerFromAllowlist, safeEqualSecret } from "openclaw/plugin-sdk/security-runtime";
29
30
  import * as crypto$1 from "node:crypto";
30
31
  import crypto from "node:crypto";
31
32
  import { resolveChannelConfigWrites } from "openclaw/plugin-sdk/channel-config-writes";
@@ -2466,6 +2467,33 @@ async function handleFeishuMessage(params) {
2466
2467
  const configReplyInThread = isGroup && (groupConfig?.replyInThread ?? feishuCfg?.replyInThread ?? "disabled") === "enabled";
2467
2468
  const replyTargetMessageId = isTopicSession || configReplyInThread ? ctx.rootId ?? ctx.replyTargetMessageId ?? (ctx.suppressReplyTarget ? void 0 : ctx.messageId) : ctx.replyTargetMessageId ?? (ctx.suppressReplyTarget ? void 0 : ctx.messageId);
2468
2469
  const threadReply = isGroup ? groupSession?.threadReply ?? false : false;
2470
+ const lastRouteThreadId = isGroup && (isTopicSession || configReplyInThread || threadReply) ? replyTargetMessageId : void 0;
2471
+ const pinnedMainDmOwner = !isGroup ? resolvePinnedMainDmOwnerFromAllowlist({
2472
+ dmScope: cfg.session?.dmScope,
2473
+ allowFrom: configAllowFrom,
2474
+ normalizeEntry: normalizeFeishuAllowEntry
2475
+ }) : null;
2476
+ const pinnedMainDmSenderRecipient = pinnedMainDmOwner ? [ctx.senderOpenId, senderUserId].map((id) => id ? normalizeFeishuAllowEntry(id) : "").find((recipient) => recipient === pinnedMainDmOwner) : void 0;
2477
+ const buildFeishuInboundLastRouteUpdate = (params) => {
2478
+ const inboundLastRouteSessionKey = params.sessionKey === route.sessionKey ? resolveInboundLastRouteSessionKey({
2479
+ route,
2480
+ sessionKey: params.sessionKey
2481
+ }) : params.sessionKey;
2482
+ return {
2483
+ sessionKey: inboundLastRouteSessionKey,
2484
+ channel: "feishu",
2485
+ to: feishuTo,
2486
+ accountId: params.accountId,
2487
+ ...lastRouteThreadId ? { threadId: lastRouteThreadId } : {},
2488
+ mainDmOwnerPin: !isGroup && inboundLastRouteSessionKey === route.mainSessionKey && pinnedMainDmOwner ? {
2489
+ ownerRecipient: pinnedMainDmOwner,
2490
+ senderRecipient: pinnedMainDmSenderRecipient ?? feishuTo,
2491
+ onSkip: (skipParams) => {
2492
+ log(`feishu[${account.accountId}]: skip main-session last route for ${skipParams.senderRecipient} (pinned owner ${skipParams.ownerRecipient})`);
2493
+ }
2494
+ } : void 0
2495
+ };
2496
+ };
2469
2497
  if (broadcastAgents) {
2470
2498
  if (!await tryRecordMessagePersistent(messageDedupeKey ?? ctx.messageId, "broadcast", log)) {
2471
2499
  log(`feishu[${account.accountId}]: broadcast already claimed by another account for message ${ctx.messageId}; skipping`);
@@ -2483,9 +2511,15 @@ async function handleFeishuMessage(params) {
2483
2511
  }
2484
2512
  const agentSessionKey = buildBroadcastSessionKey(route.sessionKey, route.agentId, agentId);
2485
2513
  const agentStorePath = core.channel.session.resolveStorePath(cfg.session?.store, { agentId });
2486
- const agentRecord = { onRecordError: (err) => {
2487
- log(`feishu[${account.accountId}]: failed to record broadcast inbound session ${agentSessionKey}: ${String(err)}`);
2488
- } };
2514
+ const agentRecord = {
2515
+ updateLastRoute: buildFeishuInboundLastRouteUpdate({
2516
+ sessionKey: agentSessionKey,
2517
+ accountId: route.accountId
2518
+ }),
2519
+ onRecordError: (err) => {
2520
+ log(`feishu[${account.accountId}]: failed to record broadcast inbound session ${agentSessionKey}: ${String(err)}`);
2521
+ }
2522
+ };
2489
2523
  const allowReasoningPreview = resolveFeishuReasoningPreviewEnabled({
2490
2524
  cfg,
2491
2525
  agentId,
@@ -2663,9 +2697,15 @@ async function handleFeishuMessage(params) {
2663
2697
  storePath,
2664
2698
  ctxPayload,
2665
2699
  recordInboundSession: core.channel.session.recordInboundSession,
2666
- record: { onRecordError: (err) => {
2667
- log(`feishu[${account.accountId}]: failed to record inbound session ${route.sessionKey}: ${String(err)}`);
2668
- } },
2700
+ record: {
2701
+ updateLastRoute: buildFeishuInboundLastRouteUpdate({
2702
+ sessionKey: route.sessionKey,
2703
+ accountId: route.accountId
2704
+ }),
2705
+ onRecordError: (err) => {
2706
+ log(`feishu[${account.accountId}]: failed to record inbound session ${route.sessionKey}: ${String(err)}`);
2707
+ }
2708
+ },
2669
2709
  history: {
2670
2710
  isGroup,
2671
2711
  historyKey,
@@ -3903,7 +3943,7 @@ async function resolveDriveCommentEventCore(params) {
3903
3943
  return null;
3904
3944
  }
3905
3945
  const context = await fetchDriveCommentContext({
3906
- client: createClient ? createClient(account ?? { accountId }) : createFeishuClient((await import("./accounts-CP4tDW-z.js").then((n) => n.t)).resolveFeishuAccount({
3946
+ client: createClient ? createClient(account ?? { accountId }) : createFeishuClient((await import("./accounts-QNGhjZeI.js").then((n) => n.t)).resolveFeishuAccount({
3907
3947
  cfg,
3908
3948
  accountId
3909
3949
  })),
@@ -4857,7 +4897,7 @@ async function resolveReactionSyntheticEvent(params) {
4857
4897
  const senderId = event.user_id?.open_id;
4858
4898
  const senderUserId = event.user_id?.user_id;
4859
4899
  if (!emoji || !messageId || !senderId) return null;
4860
- const { resolveFeishuAccount } = await import("./accounts-CP4tDW-z.js").then((n) => n.t);
4900
+ const { resolveFeishuAccount } = await import("./accounts-QNGhjZeI.js").then((n) => n.t);
4861
4901
  const reactionNotifications = resolveFeishuAccount({
4862
4902
  cfg,
4863
4903
  accountId
@@ -1,6 +1,6 @@
1
1
  import { i as resolveReceiveIdType, r as normalizeFeishuTarget } from "./targets-Bb05cFr4.js";
2
- import { c as createFeishuApiError, f as isRecord$2, g as requestFeishuApi, s as resolveFeishuRuntimeAccount } from "./accounts-CP4tDW-z.js";
3
- import { c as toFeishuSendResult, o as assertFeishuMessageApiSuccess, s as resolveFeishuReceiptKind } from "./channel-DLhJC9t0.js";
2
+ import { c as createFeishuApiError, f as isRecord$2, g as requestFeishuApi, s as resolveFeishuRuntimeAccount } from "./accounts-QNGhjZeI.js";
3
+ import { c as toFeishuSendResult, o as assertFeishuMessageApiSuccess, s as resolveFeishuReceiptKind } from "./channel-elV7bWCs.js";
4
4
  import { t as getFeishuRuntime } from "./runtime-Cc16UY23.js";
5
5
  import { r as createFeishuClient } from "./client-B18oTGHf.js";
6
6
  import { normalizeLowercaseStringOrEmpty, normalizeOptionalLowercaseString } from "openclaw/plugin-sdk/string-coerce-runtime";
package/dist/setup-api.js CHANGED
@@ -1,2 +1,2 @@
1
- import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-DLhJC9t0.js";
1
+ import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-elV7bWCs.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.16-beta.3",
3
+ "version": "2026.5.16-beta.5",
4
4
  "description": "OpenClaw Feishu/Lark channel plugin (community maintained by @m1heng)",
5
5
  "repository": {
6
6
  "type": "git",
@@ -17,7 +17,7 @@
17
17
  "openclaw": "workspace:*"
18
18
  },
19
19
  "peerDependencies": {
20
- "openclaw": ">=2026.5.16-beta.3"
20
+ "openclaw": ">=2026.5.16-beta.5"
21
21
  },
22
22
  "peerDependenciesMeta": {
23
23
  "openclaw": {
@@ -48,10 +48,10 @@
48
48
  "minHostVersion": ">=2026.4.25"
49
49
  },
50
50
  "compat": {
51
- "pluginApi": ">=2026.5.16-beta.3"
51
+ "pluginApi": ">=2026.5.16-beta.5"
52
52
  },
53
53
  "build": {
54
- "openclawVersion": "2026.5.16-beta.3"
54
+ "openclawVersion": "2026.5.16-beta.5"
55
55
  },
56
56
  "release": {
57
57
  "publishToClawHub": true,
@@ -8,6 +8,8 @@ description: |
8
8
 
9
9
  Single tool `feishu_wiki` for knowledge base operations.
10
10
 
11
+ Wiki `space_id` values are opaque strings. Always keep them quoted in tool calls, even when they contain only digits; passing a long numeric-looking ID as a number can corrupt the suffix due to JavaScript number precision limits.
12
+
11
13
  ## Token Extraction
12
14
 
13
15
  From URL `https://xxx.feishu.cn/wiki/ABC123def` → `token` = `ABC123def`