@openclaw/feishu 2026.6.11-beta.2 → 2026.7.1-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api.js +1 -1
- package/dist/{app-registration-tgQJUcv3.js → app-registration-DapxBG7t.js} +1 -1
- package/dist/{channel-C1MthXp0.js → channel-C1Uun9zo.js} +12 -7
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-CiQqumBC.js → channel.runtime-Cjc4wDNg.js} +5 -5
- package/dist/{monitor-CxUQtU--.js → monitor-CQo4C7q9.js} +6 -4
- package/dist/{monitor.account-C3SH96dD.js → monitor.account-08br3nkU.js} +113 -35
- package/dist/{monitor.state-CGL1occz.js → monitor.state-R4ZgNpac.js} +1 -1
- package/dist/{probe-EyeJQb3C.js → probe-Cv2M2Ivr.js} +2 -1
- package/dist/runtime-api.js +2 -2
- package/dist/{secret-contract-ChjJKAJ9.js → secret-contract-DLaBl9m4.js} +26 -8
- package/dist/secret-contract-api.js +1 -1
- package/dist/{send-B0nDqief.js → send-BcPh0I15.js} +24 -1
- package/dist/setup-api.js +1 -1
- package/npm-shrinkwrap.json +3 -3
- package/package.json +4 -4
package/dist/api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as listEnabledFeishuAccounts } from "./accounts-Cfzht2Hc.js";
|
|
2
|
-
import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-
|
|
2
|
+
import { a as setFeishuNamedAccountEnabled, i as feishuSetupAdapter, n as feishuSetupWizard, r as runFeishuLogin, t as feishuPlugin } from "./channel-C1Uun9zo.js";
|
|
3
3
|
import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
|
|
4
4
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
5
5
|
import { r as createFeishuClient } from "./client-BwgAJuvo.js";
|
|
@@ -135,7 +135,7 @@ async function pollAppRegistration(params) {
|
|
|
135
135
|
* otherwise the pattern is corrupted and cannot be scanned.
|
|
136
136
|
*/
|
|
137
137
|
async function printQrCode(url) {
|
|
138
|
-
const output = await renderQrTerminal(url);
|
|
138
|
+
const output = await renderQrTerminal(url, { small: true });
|
|
139
139
|
process.stdout.write(output.endsWith("\n") ? output : `${output}\n`);
|
|
140
140
|
}
|
|
141
141
|
/**
|
|
@@ -3,14 +3,14 @@ import { n as looksLikeFeishuId, r as normalizeFeishuTarget, t as detectIdType }
|
|
|
3
3
|
import { n as createFeishuSendReceipt, s as createFeishuCardInteractionEnvelope } from "./send-result-DSsIa4-p.js";
|
|
4
4
|
import { a as parseFeishuTargetId, i as parseFeishuDirectConversationId, n as buildFeishuModelOverrideParentCandidates, r as parseFeishuConversationId, t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
|
|
5
5
|
import { t as messageActionTargetAliases } from "./security-audit-BIeA3W3Q.js";
|
|
6
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-
|
|
6
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries } from "./secret-contract-DLaBl9m4.js";
|
|
7
7
|
import { t as collectFeishuSecurityAuditFindings } from "./security-audit-shared-BIHeF-S_.js";
|
|
8
8
|
import { t as resolveFeishuSessionConversation } from "./session-conversation-CZSMgac-.js";
|
|
9
9
|
import { describeAccountSnapshot } from "openclaw/plugin-sdk/account-helpers";
|
|
10
10
|
import { formatAllowFromLowercase } from "openclaw/plugin-sdk/allow-from";
|
|
11
11
|
import { adaptScopedAccountAccessor, createHybridChannelConfigAdapter } from "openclaw/plugin-sdk/channel-config-helpers";
|
|
12
12
|
import { buildChannelOutboundSessionRoute, createChatChannelPlugin, stripChannelTargetPrefix } from "openclaw/plugin-sdk/channel-core";
|
|
13
|
-
import { createRuntimeOutboundDelegates, defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
|
|
13
|
+
import { createAccountStatusSink, createRuntimeOutboundDelegates, defineChannelMessageAdapter } from "openclaw/plugin-sdk/channel-outbound";
|
|
14
14
|
import { createPairingPrefixStripper } from "openclaw/plugin-sdk/channel-pairing";
|
|
15
15
|
import { createAllowlistProviderGroupPolicyWarningCollector, projectConfigAccountIdWarningCollector } from "openclaw/plugin-sdk/channel-policy";
|
|
16
16
|
import { getSessionBindingService } from "openclaw/plugin-sdk/conversation-runtime";
|
|
@@ -1433,7 +1433,7 @@ function applyNewAppSecurityPolicy(cfg, accountId, openId, groupPolicy) {
|
|
|
1433
1433
|
}
|
|
1434
1434
|
let appRegistrationModulePromise = null;
|
|
1435
1435
|
const loadAppRegistrationModule = async () => {
|
|
1436
|
-
appRegistrationModulePromise ??= import("./app-registration-
|
|
1436
|
+
appRegistrationModulePromise ??= import("./app-registration-DapxBG7t.js");
|
|
1437
1437
|
return await appRegistrationModulePromise;
|
|
1438
1438
|
};
|
|
1439
1439
|
async function promptFeishuDomain(params) {
|
|
@@ -1659,7 +1659,7 @@ const feishuSetupWizard = {
|
|
|
1659
1659
|
});
|
|
1660
1660
|
let probeResult = null;
|
|
1661
1661
|
if (configured && account.configured) try {
|
|
1662
|
-
const { probeFeishu } = await import("./probe-
|
|
1662
|
+
const { probeFeishu } = await import("./probe-Cv2M2Ivr.js").then((n) => n.n);
|
|
1663
1663
|
probeResult = await probeFeishu(account);
|
|
1664
1664
|
} catch {}
|
|
1665
1665
|
if (!configured) return [formatFeishuStatusLine("needs-credentials")];
|
|
@@ -1735,7 +1735,7 @@ const meta = {
|
|
|
1735
1735
|
order: 70,
|
|
1736
1736
|
preferSessionLookupForAnnounceTarget: true
|
|
1737
1737
|
};
|
|
1738
|
-
const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-
|
|
1738
|
+
const loadFeishuChannelRuntime = createLazyRuntimeNamedExport(() => import("./channel.runtime-Cjc4wDNg.js"), "feishuChannelRuntime");
|
|
1739
1739
|
function toFeishuMessageSendResult(result, kind) {
|
|
1740
1740
|
const receipt = result.receipt ?? createFeishuSendReceipt({
|
|
1741
1741
|
messageId: result.messageId,
|
|
@@ -2551,7 +2551,7 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2551
2551
|
})
|
|
2552
2552
|
}),
|
|
2553
2553
|
gateway: { startAccount: async (ctx) => {
|
|
2554
|
-
const { monitorFeishuProvider } = await import("./monitor-
|
|
2554
|
+
const { monitorFeishuProvider } = await import("./monitor-CQo4C7q9.js");
|
|
2555
2555
|
const account = resolveFeishuRuntimeAccount({
|
|
2556
2556
|
cfg: ctx.cfg,
|
|
2557
2557
|
accountId: ctx.accountId
|
|
@@ -2562,12 +2562,17 @@ const feishuPlugin = createChatChannelPlugin({
|
|
|
2562
2562
|
port
|
|
2563
2563
|
});
|
|
2564
2564
|
ctx.log?.info(`starting feishu[${ctx.accountId}] (mode: ${account.config?.connectionMode ?? "websocket"})`);
|
|
2565
|
+
const statusSink = createAccountStatusSink({
|
|
2566
|
+
accountId: ctx.accountId,
|
|
2567
|
+
setStatus: ctx.setStatus
|
|
2568
|
+
});
|
|
2565
2569
|
return monitorFeishuProvider({
|
|
2566
2570
|
config: ctx.cfg,
|
|
2567
2571
|
runtime: ctx.runtime,
|
|
2568
2572
|
channelRuntime: ctx.channelRuntime,
|
|
2569
2573
|
abortSignal: ctx.abortSignal,
|
|
2570
|
-
accountId: ctx.accountId
|
|
2574
|
+
accountId: ctx.accountId,
|
|
2575
|
+
statusSink
|
|
2571
2576
|
});
|
|
2572
2577
|
} },
|
|
2573
2578
|
message: feishuMessageAdapter
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as feishuPlugin } from "./channel-
|
|
1
|
+
import { t as feishuPlugin } from "./channel-C1Uun9zo.js";
|
|
2
2
|
export { feishuPlugin };
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount, v as parseFeishuCommentTarget } from "./accounts-Cfzht2Hc.js";
|
|
2
|
-
import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-
|
|
2
|
+
import { h as listFeishuDirectoryPeers, m as listFeishuDirectoryGroups, o as buildFeishuPresentationCardElements } from "./channel-C1Uun9zo.js";
|
|
3
3
|
import { r as createFeishuClient } from "./client-BwgAJuvo.js";
|
|
4
4
|
import { c as getChatInfo, l as getChatMembers, r as cleanupAmbientCommentTypingReaction, t as deliverCommentThreadText, u as getFeishuMemberInfo } from "./drive-djUl8IRC.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-
|
|
7
|
-
import { t as probeFeishu } from "./probe-
|
|
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, y as resolveFeishuIdentityHeaderTitle } from "./send-BcPh0I15.js";
|
|
7
|
+
import { t as probeFeishu } from "./probe-Cv2M2Ivr.js";
|
|
8
8
|
import { interactiveReplyToPresentation, normalizeInteractiveReply, normalizeMessagePresentation, renderMessagePresentationFallbackText, resolveInteractiveTextFallback } from "openclaw/plugin-sdk/interactive-runtime";
|
|
9
9
|
import { isRecord, normalizeLowercaseStringOrEmpty, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
10
10
|
import path from "node:path";
|
|
@@ -230,7 +230,7 @@ function buildFeishuPayloadCard(params) {
|
|
|
230
230
|
presentation
|
|
231
231
|
})
|
|
232
232
|
}];
|
|
233
|
-
const identityTitle = params.identity
|
|
233
|
+
const identityTitle = resolveFeishuIdentityHeaderTitle(params.identity);
|
|
234
234
|
const title = presentation?.title ?? identityTitle;
|
|
235
235
|
const template = resolveFeishuCardTemplate(presentation?.tone === "danger" ? "red" : presentation?.tone === "warning" ? "orange" : presentation?.tone === "success" ? "green" : "blue");
|
|
236
236
|
return markRenderedFeishuCard({
|
|
@@ -463,7 +463,7 @@ const feishuOutbound = {
|
|
|
463
463
|
}).config?.renderMode ?? "auto";
|
|
464
464
|
if (renderMode === "card" || renderMode === "auto" && shouldUseCard(text)) {
|
|
465
465
|
const header = identity ? {
|
|
466
|
-
title: identity
|
|
466
|
+
title: resolveFeishuIdentityHeaderTitle(identity),
|
|
467
467
|
template: "blue"
|
|
468
468
|
} : void 0;
|
|
469
469
|
return await sendStructuredCardFeishu({
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { r as listEnabledFeishuAccounts, s as resolveFeishuRuntimeAccount } from "./accounts-Cfzht2Hc.js";
|
|
2
|
-
import { f as fetchBotIdentityForMonitor } from "./monitor.state-
|
|
2
|
+
import { f as fetchBotIdentityForMonitor } from "./monitor.state-R4ZgNpac.js";
|
|
3
3
|
//#region extensions/feishu/src/monitor.ts
|
|
4
4
|
let monitorAccountRuntimePromise;
|
|
5
5
|
async function loadMonitorAccountRuntime() {
|
|
6
|
-
monitorAccountRuntimePromise ??= import("./monitor.account-
|
|
6
|
+
monitorAccountRuntimePromise ??= import("./monitor.account-08br3nkU.js");
|
|
7
7
|
return await monitorAccountRuntimePromise;
|
|
8
8
|
}
|
|
9
9
|
async function monitorFeishuProvider(opts = {}) {
|
|
@@ -22,7 +22,8 @@ async function monitorFeishuProvider(opts = {}) {
|
|
|
22
22
|
account,
|
|
23
23
|
channelRuntime: opts.channelRuntime,
|
|
24
24
|
runtime: opts.runtime,
|
|
25
|
-
abortSignal: opts.abortSignal
|
|
25
|
+
abortSignal: opts.abortSignal,
|
|
26
|
+
...opts.statusSink ? { statusSink: opts.statusSink } : {}
|
|
26
27
|
});
|
|
27
28
|
}
|
|
28
29
|
const accounts = listEnabledFeishuAccounts(cfg);
|
|
@@ -53,7 +54,8 @@ async function monitorFeishuProvider(opts = {}) {
|
|
|
53
54
|
kind: "prefetched",
|
|
54
55
|
botOpenId,
|
|
55
56
|
botName
|
|
56
|
-
}
|
|
57
|
+
},
|
|
58
|
+
...opts.statusSink ? { statusSink: opts.statusSink } : {}
|
|
57
59
|
}));
|
|
58
60
|
}
|
|
59
61
|
await Promise.all(monitorPromises);
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { _ as normalizeCommentFileType, c as encodeQuery, d as isRecord$1, f as normalizeString, g as buildFeishuCommentTarget, h as requestFeishuApi, l as extractReplyText, m as readString, o as resolveFeishuAccount, p as parseCommentContentElements, s as resolveFeishuRuntimeAccount } from "./accounts-Cfzht2Hc.js";
|
|
2
2
|
import { i as resolveReceiveIdType } from "./targets-BUjQ1TcA.js";
|
|
3
|
-
import { c as normalizeFeishuAllowEntry, d as resolveFeishuGroupConversationIngressAccess, f as resolveFeishuGroupSenderActivationIngressAccess, l as resolveFeishuDmIngressAccess, p as resolveFeishuReplyPolicy, s as hasExplicitFeishuGroupConfig, u as resolveFeishuGroupConfig } from "./channel-
|
|
3
|
+
import { c as normalizeFeishuAllowEntry, d as resolveFeishuGroupConversationIngressAccess, f as resolveFeishuGroupSenderActivationIngressAccess, l as resolveFeishuDmIngressAccess, p as resolveFeishuReplyPolicy, s as hasExplicitFeishuGroupConfig, u as resolveFeishuGroupConfig } from "./channel-C1Uun9zo.js";
|
|
4
4
|
import { c as decodeFeishuCardAction, o as buildFeishuCardActionTextFallback, s as createFeishuCardInteractionEnvelope } from "./send-result-DSsIa4-p.js";
|
|
5
5
|
import { t as buildFeishuConversationId } from "./conversation-id-DuL575sn.js";
|
|
6
6
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
7
7
|
import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient } from "./client-BwgAJuvo.js";
|
|
8
8
|
import { c as getChatInfo, i as createCommentTypingReactionLifecycle, t as deliverCommentThreadText } from "./drive-djUl8IRC.js";
|
|
9
9
|
import { t as createFeishuThreadBindingManager } from "./thread-bindings-V0bwk0A1.js";
|
|
10
|
-
import { createReplyPrefixContext, evaluateSupplementalContextVisibility,
|
|
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-
|
|
12
|
-
import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-
|
|
13
|
-
import { a as clearFeishuBotIdentityState, c as httpServers, d as wsClients, f as fetchBotIdentityForMonitor, i as botOpenIds, l as recordWebhookStatus, n as FEISHU_WEBHOOK_MAX_BODY_BYTES, o as closeTrackedFeishuHttpServer, r as botNames, s as feishuWebhookRateLimiter, t as FEISHU_WEBHOOK_BODY_TIMEOUT_MS, u as setFeishuBotIdentityState } from "./monitor.state-
|
|
10
|
+
import { createReplyPrefixContext, evaluateSupplementalContextVisibility, getSessionEntry, normalizeAgentId as normalizeAgentId$2, resolveChannelContextVisibilityMode } 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, v as resolveFeishuIdentityEmoji } from "./send-BcPh0I15.js";
|
|
12
|
+
import { i as waitForAbortableDelay, r as raceWithTimeoutAndAbort } from "./probe-Cv2M2Ivr.js";
|
|
13
|
+
import { a as clearFeishuBotIdentityState, c as httpServers, d as wsClients, f as fetchBotIdentityForMonitor, i as botOpenIds, l as recordWebhookStatus, n as FEISHU_WEBHOOK_MAX_BODY_BYTES, o as closeTrackedFeishuHttpServer, r as botNames, s as feishuWebhookRateLimiter, t as FEISHU_WEBHOOK_BODY_TIMEOUT_MS, u as setFeishuBotIdentityState } from "./monitor.state-R4ZgNpac.js";
|
|
14
14
|
import { createChannelMessageReplyPipeline, formatChannelProgressDraftLineForEntry, isChannelProgressDraftWorkToolName, resolveAgentOutboundIdentity } from "openclaw/plugin-sdk/channel-outbound";
|
|
15
15
|
import { createChannelPairingController, createChannelPairingController as createChannelPairingController$1 } from "openclaw/plugin-sdk/channel-pairing";
|
|
16
16
|
import { ensureConfiguredBindingRouteReady, resolveConfiguredBindingRoute, resolveRuntimeConversationBindingRoute } from "openclaw/plugin-sdk/conversation-runtime";
|
|
@@ -32,6 +32,7 @@ import { resolvePinnedMainDmOwnerFromAllowlist, safeEqualSecret } from "openclaw
|
|
|
32
32
|
import { buildChannelInboundEventContext, toInboundMediaFacts } from "openclaw/plugin-sdk/channel-inbound";
|
|
33
33
|
import { DEFAULT_GROUP_HISTORY_LIMIT, createChannelHistoryWindow } from "openclaw/plugin-sdk/reply-history";
|
|
34
34
|
import { resolveDefaultGroupPolicy, resolveOpenProviderRuntimeGroupPolicy, warnMissingProviderGroupPolicyFallbackOnce } from "openclaw/plugin-sdk/runtime-group-policy";
|
|
35
|
+
import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
35
36
|
import { resolveChannelConfigWrites } from "openclaw/plugin-sdk/channel-config-writes";
|
|
36
37
|
import { formatReasoningMessage } from "openclaw/plugin-sdk/agent-runtime";
|
|
37
38
|
import { logTypingFailure } from "openclaw/plugin-sdk/channel-feedback";
|
|
@@ -844,10 +845,11 @@ function resolveFeishuReasoningPreviewEnabled(params) {
|
|
|
844
845
|
const configDefault = resolveFeishuConfigReasoningDefault(params.cfg, params.agentId);
|
|
845
846
|
if (!params.sessionKey) return configDefault === "stream";
|
|
846
847
|
try {
|
|
847
|
-
const level =
|
|
848
|
-
|
|
849
|
-
sessionKey: params.sessionKey
|
|
850
|
-
|
|
848
|
+
const level = getSessionEntry({
|
|
849
|
+
storePath: params.storePath,
|
|
850
|
+
sessionKey: params.sessionKey,
|
|
851
|
+
readConsistency: "latest"
|
|
852
|
+
})?.reasoningLevel;
|
|
851
853
|
if (level === "on" || level === "stream" || level === "off") return level === "stream";
|
|
852
854
|
} catch {
|
|
853
855
|
return false;
|
|
@@ -919,7 +921,7 @@ async function getToken(creds) {
|
|
|
919
921
|
function truncateSummary(text, max = 50) {
|
|
920
922
|
if (!text) return "";
|
|
921
923
|
const clean = text.replace(/\n/g, " ").trim();
|
|
922
|
-
return clean.length <= max ? clean : clean
|
|
924
|
+
return clean.length <= max ? clean : sliceUtf16Safe(clean, 0, max - 3) + "...";
|
|
923
925
|
}
|
|
924
926
|
function hasNaturalStreamingBoundary(text) {
|
|
925
927
|
return /[\n。!?!?;;::]$/.test(text);
|
|
@@ -1455,7 +1457,7 @@ function normalizeEpochMs(timestamp) {
|
|
|
1455
1457
|
/** Build a card header from agent identity config. */
|
|
1456
1458
|
function resolveCardHeader(agentId, identity) {
|
|
1457
1459
|
const name = identity?.name?.trim() || (agentId === "main" ? "" : agentId);
|
|
1458
|
-
const emoji = identity?.emoji
|
|
1460
|
+
const emoji = resolveFeishuIdentityEmoji(identity?.emoji);
|
|
1459
1461
|
const title = (emoji ? `${emoji} ${name}` : name).trim();
|
|
1460
1462
|
if (!title) return;
|
|
1461
1463
|
return {
|
|
@@ -1472,7 +1474,7 @@ function resolveCardNote(agentId, identity, prefixCtx) {
|
|
|
1472
1474
|
}
|
|
1473
1475
|
function createFeishuReplyDispatcher(params) {
|
|
1474
1476
|
const core = getFeishuRuntime();
|
|
1475
|
-
const { cfg, agentId, chatId, replyToMessageId, typingTargetMessageId: explicitTypingTargetMessageId, skipReplyToInMessages, replyInThread, threadReply, rootId, accountId, identity, mentionTargets } = params;
|
|
1477
|
+
const { cfg, agentId, chatId, sendTarget, replyToMessageId, typingTargetMessageId: explicitTypingTargetMessageId, skipReplyToInMessages, replyInThread, threadReply, rootId, accountId, identity, mentionTargets } = params;
|
|
1476
1478
|
const sendReplyToMessageId = skipReplyToInMessages ? void 0 : replyToMessageId;
|
|
1477
1479
|
const typingTargetMessageId = explicitTypingTargetMessageId?.trim() || replyToMessageId;
|
|
1478
1480
|
const threadReplyMode = threadReply === true;
|
|
@@ -1549,6 +1551,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1549
1551
|
let lastSnapshotTextLength = 0;
|
|
1550
1552
|
let hasStreamingFinalText = false;
|
|
1551
1553
|
const deliveredFinalTexts = /* @__PURE__ */ new Set();
|
|
1554
|
+
let sentIndependentBlockText = false;
|
|
1552
1555
|
let partialUpdateQueue = Promise.resolve();
|
|
1553
1556
|
let streamingStartPromise = null;
|
|
1554
1557
|
let streamingClosedForReply = false;
|
|
@@ -1611,8 +1614,9 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1611
1614
|
try {
|
|
1612
1615
|
const cardHeader = resolveCardHeader(agentId, identity);
|
|
1613
1616
|
const cardNote = resolveCardNote(agentId, identity, prefixContext.prefixContext);
|
|
1614
|
-
|
|
1615
|
-
|
|
1617
|
+
const streamingTarget = sendTarget.replace(/^(feishu|lark):/i, "").replace(/^(chat|user|group|dm|open_id):/i, "").trim();
|
|
1618
|
+
await streaming.start(streamingTarget, resolveReceiveIdType(sendTarget), {
|
|
1619
|
+
replyToMessageId: sendReplyToMessageId,
|
|
1616
1620
|
replyInThread: effectiveReplyInThread,
|
|
1617
1621
|
rootId,
|
|
1618
1622
|
header: cardHeader,
|
|
@@ -1694,7 +1698,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1694
1698
|
send: async ({ mediaUrl }) => {
|
|
1695
1699
|
const result = await sendMediaFeishu({
|
|
1696
1700
|
cfg,
|
|
1697
|
-
to:
|
|
1701
|
+
to: sendTarget,
|
|
1698
1702
|
mediaUrl,
|
|
1699
1703
|
replyToMessageId: sendReplyToMessageId,
|
|
1700
1704
|
replyInThread: effectiveReplyInThread,
|
|
@@ -1711,7 +1715,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1711
1715
|
sendChunk: async ({ chunk }) => {
|
|
1712
1716
|
await sendMessageFeishu({
|
|
1713
1717
|
cfg,
|
|
1714
|
-
to:
|
|
1718
|
+
to: sendTarget,
|
|
1715
1719
|
text: chunk,
|
|
1716
1720
|
replyToMessageId: sendReplyToMessageId,
|
|
1717
1721
|
replyInThread: effectiveReplyInThread,
|
|
@@ -1732,7 +1736,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1732
1736
|
sendChunk: async ({ chunk }) => {
|
|
1733
1737
|
await sendMessageFeishu({
|
|
1734
1738
|
cfg,
|
|
1735
|
-
to:
|
|
1739
|
+
to: sendTarget,
|
|
1736
1740
|
text: chunk,
|
|
1737
1741
|
replyToMessageId: sendReplyToMessageId,
|
|
1738
1742
|
replyInThread: effectiveReplyInThread,
|
|
@@ -1753,7 +1757,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1753
1757
|
}
|
|
1754
1758
|
await sendMessageFeishu({
|
|
1755
1759
|
cfg,
|
|
1756
|
-
to:
|
|
1760
|
+
to: sendTarget,
|
|
1757
1761
|
text: NO_VISIBLE_REPLY_FALLBACK_TEXT,
|
|
1758
1762
|
replyToMessageId: sendReplyToMessageId,
|
|
1759
1763
|
replyInThread: effectiveReplyInThread,
|
|
@@ -1789,6 +1793,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1789
1793
|
if (!replyLifecycleStateInitialized) {
|
|
1790
1794
|
replyLifecycleStateInitialized = true;
|
|
1791
1795
|
deliveredFinalTexts.clear();
|
|
1796
|
+
sentIndependentBlockText = false;
|
|
1792
1797
|
streamingClosedForReply = false;
|
|
1793
1798
|
streamingCloseErroredForReply = false;
|
|
1794
1799
|
visibleReplySent = false;
|
|
@@ -1824,7 +1829,31 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1824
1829
|
if (shouldDiscardStreamingPreview) await discardStreamingPreview();
|
|
1825
1830
|
if (shouldDeliverText) {
|
|
1826
1831
|
if (info?.kind === "block") {
|
|
1827
|
-
if (!useStreamingCard)
|
|
1832
|
+
if (!useStreamingCard) {
|
|
1833
|
+
if (coreBlockStreamingEnabled) {
|
|
1834
|
+
const isFirstBlock = !sentIndependentBlockText;
|
|
1835
|
+
await sendChunkedTextReply({
|
|
1836
|
+
text,
|
|
1837
|
+
useCard: false,
|
|
1838
|
+
infoKind: "block",
|
|
1839
|
+
sendChunk: async ({ chunk, isFirst }) => {
|
|
1840
|
+
await sendMessageFeishu({
|
|
1841
|
+
cfg,
|
|
1842
|
+
to: sendTarget,
|
|
1843
|
+
text: chunk,
|
|
1844
|
+
replyToMessageId: sendReplyToMessageId,
|
|
1845
|
+
replyInThread: effectiveReplyInThread,
|
|
1846
|
+
allowTopLevelReplyFallback,
|
|
1847
|
+
accountId,
|
|
1848
|
+
...isFirstBlock && isFirst && mentionTargets?.length ? { mentions: mentionTargets } : {}
|
|
1849
|
+
});
|
|
1850
|
+
}
|
|
1851
|
+
});
|
|
1852
|
+
sentIndependentBlockText = true;
|
|
1853
|
+
if (hasMedia) await sendMediaReplies(payload);
|
|
1854
|
+
}
|
|
1855
|
+
return;
|
|
1856
|
+
}
|
|
1828
1857
|
startStreaming();
|
|
1829
1858
|
if (streamingStartPromise) await streamingStartPromise;
|
|
1830
1859
|
}
|
|
@@ -1858,7 +1887,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1858
1887
|
sendChunk: async ({ chunk }) => {
|
|
1859
1888
|
await sendStructuredCardFeishu({
|
|
1860
1889
|
cfg,
|
|
1861
|
-
to:
|
|
1890
|
+
to: sendTarget,
|
|
1862
1891
|
text: chunk,
|
|
1863
1892
|
replyToMessageId: sendReplyToMessageId,
|
|
1864
1893
|
replyInThread: effectiveReplyInThread,
|
|
@@ -1876,7 +1905,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1876
1905
|
sendChunk: async ({ chunk, isFirst }) => {
|
|
1877
1906
|
await sendMessageFeishu({
|
|
1878
1907
|
cfg,
|
|
1879
|
-
to:
|
|
1908
|
+
to: sendTarget,
|
|
1880
1909
|
text: chunk,
|
|
1881
1910
|
replyToMessageId: sendReplyToMessageId,
|
|
1882
1911
|
replyInThread: effectiveReplyInThread,
|
|
@@ -2098,7 +2127,7 @@ function formatMentionNameForAgentContext(name) {
|
|
|
2098
2127
|
const normalized = Array.from(name, (char) => {
|
|
2099
2128
|
return char.charCodeAt(0) < 32 || char === "[" || char === "]" ? " " : char;
|
|
2100
2129
|
}).join("").replace(/\s+/g, " ").trim();
|
|
2101
|
-
const bounded = normalized.length > MAX_MENTION_CONTEXT_NAME_LENGTH ? `${normalized
|
|
2130
|
+
const bounded = normalized.length > MAX_MENTION_CONTEXT_NAME_LENGTH ? `${truncateUtf16Safe(normalized, MAX_MENTION_CONTEXT_NAME_LENGTH - 3)}...` : normalized;
|
|
2102
2131
|
return JSON.stringify(bounded || "unknown");
|
|
2103
2132
|
}
|
|
2104
2133
|
function buildFeishuAgentBody(params) {
|
|
@@ -2538,7 +2567,7 @@ async function handleFeishuMessage(params) {
|
|
|
2538
2567
|
return;
|
|
2539
2568
|
}
|
|
2540
2569
|
}
|
|
2541
|
-
const preview = ctx.content.replace(/\s+/g, " ")
|
|
2570
|
+
const preview = truncateUtf16Safe(ctx.content.replace(/\s+/g, " "), 160);
|
|
2542
2571
|
const inboundLabel = isGroup ? `Feishu[${account.accountId}] message in group ${ctx.chatId}` : `Feishu[${account.accountId}] DM from ${ctx.senderOpenId}`;
|
|
2543
2572
|
const contextVisibilityMode = resolveChannelContextVisibilityMode({
|
|
2544
2573
|
cfg: effectiveCfg,
|
|
@@ -2576,7 +2605,7 @@ async function handleFeishuMessage(params) {
|
|
|
2576
2605
|
senderType: quotedMessageInfo.senderType
|
|
2577
2606
|
})) {
|
|
2578
2607
|
quotedContent = quotedMessageInfo.content;
|
|
2579
|
-
log(`feishu[${account.accountId}]: fetched quoted message: ${quotedContent
|
|
2608
|
+
log(`feishu[${account.accountId}]: fetched quoted message: ${truncateUtf16Safe(quotedContent, 100)}`);
|
|
2580
2609
|
} else if (quotedMessageInfo) log(`feishu[${account.accountId}]: skipped quoted message from sender ${quotedMessageInfo.senderId ?? "unknown"} (mode=${contextVisibilityMode})`);
|
|
2581
2610
|
} catch (err) {
|
|
2582
2611
|
log(`feishu[${account.accountId}]: failed to fetch quoted message: ${String(err)}`);
|
|
@@ -2906,6 +2935,7 @@ async function handleFeishuMessage(params) {
|
|
|
2906
2935
|
agentId,
|
|
2907
2936
|
runtime,
|
|
2908
2937
|
chatId: ctx.chatId,
|
|
2938
|
+
sendTarget: feishuTo,
|
|
2909
2939
|
allowReasoningPreview,
|
|
2910
2940
|
replyToMessageId: replyTargetMessageId,
|
|
2911
2941
|
typingTargetMessageId,
|
|
@@ -3049,6 +3079,7 @@ async function handleFeishuMessage(params) {
|
|
|
3049
3079
|
agentId: route.agentId,
|
|
3050
3080
|
runtime,
|
|
3051
3081
|
chatId: ctx.chatId,
|
|
3082
|
+
sendTarget: feishuTo,
|
|
3052
3083
|
allowReasoningPreview,
|
|
3053
3084
|
replyToMessageId: replyTargetMessageId,
|
|
3054
3085
|
typingTargetMessageId,
|
|
@@ -3901,7 +3932,7 @@ function safeJsonStringify(value) {
|
|
|
3901
3932
|
function truncatePromptText(text, maxLength = FEISHU_PROMPT_TEXT_LIMIT) {
|
|
3902
3933
|
const normalized = normalizeString(text);
|
|
3903
3934
|
if (!normalized) return "";
|
|
3904
|
-
return normalized.length > maxLength ? `${normalized
|
|
3935
|
+
return normalized.length > maxLength ? `${sliceUtf16Safe(normalized, 0, maxLength - 1)}…` : normalized;
|
|
3905
3936
|
}
|
|
3906
3937
|
function formatPromptTextValue(text) {
|
|
3907
3938
|
return safeJsonStringify(truncatePromptText(text) || "");
|
|
@@ -4474,7 +4505,7 @@ async function resolveDriveCommentEventTurn(params) {
|
|
|
4474
4505
|
nearestBotWholeCommentAfter: resolved.context.nearestBotWholeCommentAfter,
|
|
4475
4506
|
nearestBotWholeCommentBefore: resolved.context.nearestBotWholeCommentBefore
|
|
4476
4507
|
});
|
|
4477
|
-
const preview = prompt.replace(/\s+/g, " ")
|
|
4508
|
+
const preview = truncateUtf16Safe(prompt.replace(/\s+/g, " "), 160);
|
|
4478
4509
|
return {
|
|
4479
4510
|
eventId: resolved.eventId,
|
|
4480
4511
|
messageId: `drive-comment:${resolved.eventId}`,
|
|
@@ -4933,7 +4964,7 @@ function resolveFeishuDebounceMentions(params) {
|
|
|
4933
4964
|
const botMentions = merged.filter((mention) => mention.id.open_id?.trim() === normalizedBotOpenId);
|
|
4934
4965
|
return botMentions.length > 0 ? botMentions : void 0;
|
|
4935
4966
|
}
|
|
4936
|
-
function createFeishuMessageReceiveHandler({ cfg, channelRuntime, accountId, runtime, chatHistories, fireAndForget, handleMessage, resolveDebounceText: resolveText, hasProcessedMessage, recordProcessedMessage, getBotOpenId = () => void 0, getBotName = () => void 0, resolveSequentialKey = ({ accountId: accountIdLocal, event }) => `feishu:${accountIdLocal}:${event.message.chat_id?.trim() || "unknown"}
|
|
4967
|
+
function createFeishuMessageReceiveHandler({ cfg, channelRuntime, accountId, runtime, chatHistories, fireAndForget, handleMessage, resolveDebounceText: resolveText, hasProcessedMessage, recordProcessedMessage, getBotOpenId = () => void 0, getBotName = () => void 0, resolveSequentialKey = ({ accountId: accountIdLocal, event }) => `feishu:${accountIdLocal}:${event.message.chat_id?.trim() || "unknown"}`, statusSink }) {
|
|
4937
4968
|
const inboundDebounceMs = channelRuntime.debounce.resolveInboundDebounceMs({
|
|
4938
4969
|
cfg,
|
|
4939
4970
|
channel: "feishu"
|
|
@@ -5034,6 +5065,7 @@ function createFeishuMessageReceiveHandler({ cfg, channelRuntime, accountId, run
|
|
|
5034
5065
|
}
|
|
5035
5066
|
});
|
|
5036
5067
|
return async (data) => {
|
|
5068
|
+
statusSink?.({ lastEventAt: Date.now() });
|
|
5037
5069
|
const event = parseFeishuMessageEventPayload(data);
|
|
5038
5070
|
if (!event) {
|
|
5039
5071
|
error(`feishu[${accountId}]: ignoring malformed message event payload`);
|
|
@@ -5161,7 +5193,7 @@ function waitForFeishuWsCycleEnd(params) {
|
|
|
5161
5193
|
params.terminalError.then(finish);
|
|
5162
5194
|
});
|
|
5163
5195
|
}
|
|
5164
|
-
async function monitorWebSocket({ account, accountId, runtime, abortSignal, eventDispatcher }) {
|
|
5196
|
+
async function monitorWebSocket({ account, accountId, runtime, abortSignal, eventDispatcher, statusSink }) {
|
|
5165
5197
|
const log = runtime?.log ?? console.log;
|
|
5166
5198
|
const error = runtime?.error ?? console.error;
|
|
5167
5199
|
let attempt = 0;
|
|
@@ -5180,8 +5212,28 @@ async function monitorWebSocket({ account, accountId, runtime, abortSignal, even
|
|
|
5180
5212
|
}
|
|
5181
5213
|
error(`feishu[${accountId}]: WebSocket SDK reported recoverable error: ${formatFeishuWsErrorForLog(err)}`);
|
|
5182
5214
|
};
|
|
5215
|
+
const publishWsConnected = () => {
|
|
5216
|
+
const connectedAt = Date.now();
|
|
5217
|
+
statusSink?.({
|
|
5218
|
+
connected: true,
|
|
5219
|
+
lastConnectedAt: connectedAt,
|
|
5220
|
+
lastEventAt: connectedAt,
|
|
5221
|
+
lastError: null
|
|
5222
|
+
});
|
|
5223
|
+
};
|
|
5224
|
+
const publishWsReconnecting = () => {
|
|
5225
|
+
statusSink?.({
|
|
5226
|
+
connected: false,
|
|
5227
|
+
lastEventAt: Date.now()
|
|
5228
|
+
});
|
|
5229
|
+
};
|
|
5183
5230
|
log(`feishu[${accountId}]: starting WebSocket connection...`);
|
|
5184
|
-
wsClient = await createFeishuWSClient(account, {
|
|
5231
|
+
wsClient = await createFeishuWSClient(account, {
|
|
5232
|
+
onError: handleWsError,
|
|
5233
|
+
onReady: publishWsConnected,
|
|
5234
|
+
onReconnected: publishWsConnected,
|
|
5235
|
+
onReconnecting: publishWsReconnecting
|
|
5236
|
+
});
|
|
5185
5237
|
if (abortSignal?.aborted) {
|
|
5186
5238
|
cleanupFeishuWsClient({
|
|
5187
5239
|
accountId,
|
|
@@ -5216,6 +5268,10 @@ async function monitorWebSocket({ account, accountId, runtime, abortSignal, even
|
|
|
5216
5268
|
clearIdentity: false
|
|
5217
5269
|
});
|
|
5218
5270
|
if (abortSignal?.aborted) break;
|
|
5271
|
+
statusSink?.({
|
|
5272
|
+
connected: false,
|
|
5273
|
+
lastEventAt: Date.now()
|
|
5274
|
+
});
|
|
5219
5275
|
attempt += 1;
|
|
5220
5276
|
const delayMs = getFeishuWsReconnectDelayMs(attempt);
|
|
5221
5277
|
error(`feishu[${accountId}]: WebSocket connection ended, recreating client in ${delayMs}ms: ${formatFeishuWsErrorForLog(cycleEnd)}`);
|
|
@@ -5228,6 +5284,10 @@ async function monitorWebSocket({ account, accountId, runtime, abortSignal, even
|
|
|
5228
5284
|
clearIdentity: false
|
|
5229
5285
|
});
|
|
5230
5286
|
if (abortSignal?.aborted) break;
|
|
5287
|
+
statusSink?.({
|
|
5288
|
+
connected: false,
|
|
5289
|
+
lastEventAt: Date.now()
|
|
5290
|
+
});
|
|
5231
5291
|
attempt += 1;
|
|
5232
5292
|
const delayMs = getFeishuWsReconnectDelayMs(attempt);
|
|
5233
5293
|
error(`feishu[${accountId}]: WebSocket start failed, retrying in ${delayMs}ms: ${formatFeishuWsErrorForLog(err)}`);
|
|
@@ -5241,7 +5301,7 @@ async function monitorWebSocket({ account, accountId, runtime, abortSignal, even
|
|
|
5241
5301
|
clearIdentity: true
|
|
5242
5302
|
});
|
|
5243
5303
|
}
|
|
5244
|
-
async function monitorWebhook({ account, accountId, runtime, abortSignal, eventDispatcher }) {
|
|
5304
|
+
async function monitorWebhook({ account, accountId, runtime, abortSignal, eventDispatcher, statusSink }) {
|
|
5245
5305
|
const log = runtime?.log ?? console.log;
|
|
5246
5306
|
const error = runtime?.error ?? console.error;
|
|
5247
5307
|
const encryptKey = account.encryptKey?.trim();
|
|
@@ -5254,6 +5314,13 @@ async function monitorWebhook({ account, accountId, runtime, abortSignal, eventD
|
|
|
5254
5314
|
server.on("request", (req, res) => {
|
|
5255
5315
|
res.on("finish", () => {
|
|
5256
5316
|
recordWebhookStatus(runtime, accountId, path, res.statusCode);
|
|
5317
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
5318
|
+
const inboundAt = Date.now();
|
|
5319
|
+
statusSink?.({
|
|
5320
|
+
lastEventAt: inboundAt,
|
|
5321
|
+
lastTransportActivityAt: inboundAt
|
|
5322
|
+
});
|
|
5323
|
+
}
|
|
5257
5324
|
});
|
|
5258
5325
|
if (!applyBasicWebhookRequestGuards({
|
|
5259
5326
|
req,
|
|
@@ -5338,6 +5405,13 @@ async function monitorWebhook({ account, accountId, runtime, abortSignal, eventD
|
|
|
5338
5405
|
abortSignal?.addEventListener("abort", handleAbort, { once: true });
|
|
5339
5406
|
server.listen(port, host, () => {
|
|
5340
5407
|
log(`feishu[${accountId}]: Webhook server listening on ${host}:${port}`);
|
|
5408
|
+
const webhookConnectedAt = Date.now();
|
|
5409
|
+
statusSink?.({
|
|
5410
|
+
connected: true,
|
|
5411
|
+
lastConnectedAt: webhookConnectedAt,
|
|
5412
|
+
lastEventAt: webhookConnectedAt,
|
|
5413
|
+
lastError: null
|
|
5414
|
+
});
|
|
5341
5415
|
});
|
|
5342
5416
|
server.on("error", (err) => {
|
|
5343
5417
|
error(`feishu[${accountId}]: Webhook server error: ${err}`);
|
|
@@ -5505,7 +5579,8 @@ function registerEventHandlers(eventDispatcher, context) {
|
|
|
5505
5579
|
recordProcessedMessage: recordProcessedFeishuMessage,
|
|
5506
5580
|
getBotOpenId: (id) => botOpenIds.get(id),
|
|
5507
5581
|
getBotName: (id) => botNames.get(id),
|
|
5508
|
-
resolveSequentialKey: getFeishuSequentialKey
|
|
5582
|
+
resolveSequentialKey: getFeishuSequentialKey,
|
|
5583
|
+
...context.statusSink ? { statusSink: context.statusSink } : {}
|
|
5509
5584
|
}),
|
|
5510
5585
|
"im.message.message_read_v1": async () => {},
|
|
5511
5586
|
"im.chat.access_event.bot_p2p_chat_entered_v1": async () => {},
|
|
@@ -5656,24 +5731,27 @@ async function monitorSingleAccount(params) {
|
|
|
5656
5731
|
registerEventHandlers(eventDispatcher, {
|
|
5657
5732
|
cfg,
|
|
5658
5733
|
accountId,
|
|
5659
|
-
channelRuntime: params.channelRuntime
|
|
5734
|
+
channelRuntime: params.channelRuntime?.inbound ? params.channelRuntime : getFeishuRuntime().channel,
|
|
5660
5735
|
runtime,
|
|
5661
5736
|
chatHistories,
|
|
5662
|
-
fireAndForget: params.fireAndForget ?? true
|
|
5737
|
+
fireAndForget: params.fireAndForget ?? true,
|
|
5738
|
+
...params.statusSink ? { statusSink: params.statusSink } : {}
|
|
5663
5739
|
});
|
|
5664
5740
|
if (connectionMode === "webhook") return await monitorWebhook({
|
|
5665
5741
|
account,
|
|
5666
5742
|
accountId,
|
|
5667
5743
|
runtime,
|
|
5668
5744
|
abortSignal,
|
|
5669
|
-
eventDispatcher
|
|
5745
|
+
eventDispatcher,
|
|
5746
|
+
...params.statusSink ? { statusSink: params.statusSink } : {}
|
|
5670
5747
|
});
|
|
5671
5748
|
return await monitorWebSocket({
|
|
5672
5749
|
account,
|
|
5673
5750
|
accountId,
|
|
5674
5751
|
runtime,
|
|
5675
5752
|
abortSignal,
|
|
5676
|
-
eventDispatcher
|
|
5753
|
+
eventDispatcher,
|
|
5754
|
+
...params.statusSink ? { statusSink: params.statusSink } : {}
|
|
5677
5755
|
});
|
|
5678
5756
|
} finally {
|
|
5679
5757
|
threadBindingManager?.stop();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as probeFeishu } from "./probe-
|
|
1
|
+
import { t as probeFeishu } from "./probe-Cv2M2Ivr.js";
|
|
2
2
|
import { parseStrictPositiveInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
3
3
|
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import { WEBHOOK_ANOMALY_COUNTER_DEFAULTS, WEBHOOK_RATE_LIMIT_DEFAULTS, createFixedWindowRateLimiter, createWebhookAnomalyTracker } from "openclaw/plugin-sdk/webhook-ingress";
|
|
@@ -41,6 +41,7 @@ function waitForAbortableDelay(delayMs, abortSignal) {
|
|
|
41
41
|
if (abortSignal?.aborted) return Promise.resolve(false);
|
|
42
42
|
return new Promise((resolve) => {
|
|
43
43
|
let settled = false;
|
|
44
|
+
let timer = void 0;
|
|
44
45
|
const finish = (value) => {
|
|
45
46
|
if (settled) return;
|
|
46
47
|
settled = true;
|
|
@@ -56,7 +57,7 @@ function waitForAbortableDelay(delayMs, abortSignal) {
|
|
|
56
57
|
finish(false);
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
59
|
-
|
|
60
|
+
timer = setTimeout(() => finish(true), resolveTimerTimeoutMs(delayMs, 1));
|
|
60
61
|
timer.unref?.();
|
|
61
62
|
});
|
|
62
63
|
}
|
package/dist/runtime-api.js
CHANGED
|
@@ -4,10 +4,10 @@ import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pair
|
|
|
4
4
|
import { PAIRING_APPROVED_MESSAGE, buildProbeChannelStatusSummary, createDefaultChannelRuntimeState } from "openclaw/plugin-sdk/channel-status";
|
|
5
5
|
import { chunkTextForOutbound } from "openclaw/plugin-sdk/text-chunking";
|
|
6
6
|
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
7
|
-
import {
|
|
7
|
+
import { getSessionEntry } from "openclaw/plugin-sdk/session-store-runtime";
|
|
8
8
|
import { DEFAULT_ACCOUNT_ID, buildChannelConfigSchema, createActionGate, createDedupeCache } from "openclaw/plugin-sdk/core";
|
|
9
9
|
import { buildAgentMediaPayload } from "openclaw/plugin-sdk/agent-media-payload";
|
|
10
10
|
import { evaluateSupplementalContextVisibility, filterSupplementalContextItems, resolveChannelContextVisibilityMode } from "openclaw/plugin-sdk/context-visibility-runtime";
|
|
11
11
|
import { readJsonFileWithFallback } from "openclaw/plugin-sdk/json-store";
|
|
12
12
|
import { isRequestBodyLimitError, readRequestBodyWithLimit, requestBodyErrorToText } from "openclaw/plugin-sdk/webhook-ingress";
|
|
13
|
-
export { DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, buildAgentMediaPayload, buildChannelConfigSchema, buildProbeChannelStatusSummary, chunkTextForOutbound, createActionGate, createChannelPairingController, createDedupeCache, createDefaultChannelRuntimeState, createReplyPrefixContext, evaluateSupplementalContextVisibility, filterSupplementalContextItems,
|
|
13
|
+
export { DEFAULT_ACCOUNT_ID, PAIRING_APPROVED_MESSAGE, buildAgentMediaPayload, buildChannelConfigSchema, buildProbeChannelStatusSummary, chunkTextForOutbound, createActionGate, createChannelPairingController, createDedupeCache, createDefaultChannelRuntimeState, createReplyPrefixContext, evaluateSupplementalContextVisibility, filterSupplementalContextItems, getSessionEntry, isRequestBodyLimitError, normalizeAgentId, readJsonFileWithFallback, readRequestBodyWithLimit, requestBodyErrorToText, resolveChannelContextVisibilityMode, setFeishuRuntime };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { collectConditionalChannelFieldAssignments,
|
|
1
|
+
import { collectConditionalChannelFieldAssignments, collectSecretInputAssignment, getChannelSurface, hasConfiguredSecretInputValue, hasOwnProperty, isBaseFieldActiveForChannelSurface, normalizeSecretStringValue } from "openclaw/plugin-sdk/channel-secret-basic-runtime";
|
|
2
2
|
//#region extensions/feishu/src/secret-contract.ts
|
|
3
3
|
const secretTargetRegistryEntries = [
|
|
4
4
|
{
|
|
@@ -72,16 +72,34 @@ function collectRuntimeConfigAssignments(params) {
|
|
|
72
72
|
const resolved = getChannelSurface(params.config, "feishu");
|
|
73
73
|
if (!resolved) return;
|
|
74
74
|
const { channel: feishu, surface } = resolved;
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
const topLevelAppSecretActive = surface.channelEnabled && hasConfiguredSecretInputValue(feishu.appId, params.defaults) && hasConfiguredSecretInputValue(feishu.appSecret, params.defaults) || isBaseFieldActiveForChannelSurface(surface, "appSecret");
|
|
76
|
+
collectSecretInputAssignment({
|
|
77
|
+
value: feishu.appSecret,
|
|
78
|
+
path: "channels.feishu.appSecret",
|
|
79
|
+
expected: "string",
|
|
80
80
|
defaults: params.defaults,
|
|
81
81
|
context: params.context,
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
active: topLevelAppSecretActive,
|
|
83
|
+
inactiveReason: "no enabled account inherits this top-level Feishu appSecret.",
|
|
84
|
+
apply: (value) => {
|
|
85
|
+
feishu.appSecret = value;
|
|
86
|
+
}
|
|
84
87
|
});
|
|
88
|
+
if (surface.hasExplicitAccounts) for (const { accountId, account, enabled } of surface.accounts) {
|
|
89
|
+
if (!hasOwnProperty(account, "appSecret")) continue;
|
|
90
|
+
collectSecretInputAssignment({
|
|
91
|
+
value: account.appSecret,
|
|
92
|
+
path: `channels.feishu.accounts.${accountId}.appSecret`,
|
|
93
|
+
expected: "string",
|
|
94
|
+
defaults: params.defaults,
|
|
95
|
+
context: params.context,
|
|
96
|
+
active: enabled,
|
|
97
|
+
inactiveReason: "Feishu account is disabled.",
|
|
98
|
+
apply: (value) => {
|
|
99
|
+
account.appSecret = value;
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
85
103
|
const baseConnectionMode = normalizeSecretStringValue(feishu.connectionMode) === "webhook" ? "webhook" : "websocket";
|
|
86
104
|
const resolveAccountMode = (account) => hasOwnProperty(account, "connectionMode") ? normalizeSecretStringValue(account.connectionMode) : baseConnectionMode;
|
|
87
105
|
collectConditionalChannelFieldAssignments({
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-
|
|
1
|
+
import { n as collectRuntimeConfigAssignments, r as secretTargetRegistryEntries, t as channelSecrets } from "./secret-contract-DLaBl9m4.js";
|
|
2
2
|
export { channelSecrets, collectRuntimeConfigAssignments, secretTargetRegistryEntries };
|
|
@@ -15,6 +15,29 @@ import { Readable } from "node:stream";
|
|
|
15
15
|
import { saveMediaBuffer, saveMediaStream } from "openclaw/plugin-sdk/media-store";
|
|
16
16
|
import { resolvePreferredOpenClawTmpDir, withTempDownloadPath, withTempWorkspace } from "openclaw/plugin-sdk/temp-path";
|
|
17
17
|
import { resolveMarkdownTableMode } from "openclaw/plugin-sdk/markdown-table-runtime";
|
|
18
|
+
//#region extensions/feishu/src/identity-header.ts
|
|
19
|
+
const emojiSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "grapheme" }) : null;
|
|
20
|
+
const keycapEmojiPattern = /^[0-9#*]\uFE0F?\u20E3$/u;
|
|
21
|
+
const emojiLikeSegmentPattern = /[\p{Emoji_Presentation}\p{Extended_Pictographic}\p{Regional_Indicator}]/u;
|
|
22
|
+
function splitGraphemes(input) {
|
|
23
|
+
if (!emojiSegmenter) return Array.from(input);
|
|
24
|
+
return Array.from(emojiSegmenter.segment(input), (segment) => segment.segment);
|
|
25
|
+
}
|
|
26
|
+
function isEmojiSegment(segment) {
|
|
27
|
+
return keycapEmojiPattern.test(segment) || emojiLikeSegmentPattern.test(segment);
|
|
28
|
+
}
|
|
29
|
+
function resolveFeishuIdentityEmoji(raw) {
|
|
30
|
+
const trimmed = raw?.trim();
|
|
31
|
+
if (!trimmed) return;
|
|
32
|
+
return splitGraphemes(trimmed).filter(isEmojiSegment).join("") || void 0;
|
|
33
|
+
}
|
|
34
|
+
function resolveFeishuIdentityHeaderTitle(identity) {
|
|
35
|
+
if (!identity) return "";
|
|
36
|
+
const name = identity.name?.trim() ?? "";
|
|
37
|
+
const emoji = resolveFeishuIdentityEmoji(identity.emoji);
|
|
38
|
+
return (emoji ? `${emoji} ${name}` : name).trim();
|
|
39
|
+
}
|
|
40
|
+
//#endregion
|
|
18
41
|
//#region extensions/feishu/src/external-keys.ts
|
|
19
42
|
const CONTROL_CHARS_RE = /\p{Cc}/u;
|
|
20
43
|
const MAX_EXTERNAL_KEY_LENGTH = 512;
|
|
@@ -1242,4 +1265,4 @@ async function sendMarkdownCardFeishu(params) {
|
|
|
1242
1265
|
});
|
|
1243
1266
|
}
|
|
1244
1267
|
//#endregion
|
|
1245
|
-
export { normalizeFeishuExternalKey as _, sendCardFeishu as a, sendStructuredCardFeishu as c, isFeishuBroadcastMention as d, isMentionForwardRequest as f, shouldSuppressFeishuTextForVoiceMedia as g, sendMediaFeishu as h, resolveFeishuCardTemplate as i, parsePostContent as l, saveMessageResourceFeishu as m, getMessageFeishu as n, sendMarkdownCardFeishu as o, isFeishuGroupChatType as p, listFeishuThreadMessages as r, sendMessageFeishu as s, editMessageFeishu as t, extractMentionTargets as u };
|
|
1268
|
+
export { normalizeFeishuExternalKey as _, sendCardFeishu as a, sendStructuredCardFeishu as c, isFeishuBroadcastMention as d, isMentionForwardRequest as f, shouldSuppressFeishuTextForVoiceMedia as g, sendMediaFeishu as h, resolveFeishuCardTemplate as i, parsePostContent as l, saveMessageResourceFeishu as m, getMessageFeishu as n, sendMarkdownCardFeishu as o, isFeishuGroupChatType as p, listFeishuThreadMessages as r, sendMessageFeishu as s, editMessageFeishu as t, extractMentionTargets as u, resolveFeishuIdentityEmoji as v, resolveFeishuIdentityHeaderTitle as y };
|
package/dist/setup-api.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-
|
|
1
|
+
import { i as feishuSetupAdapter, n as feishuSetupWizard, t as feishuPlugin } from "./channel-C1Uun9zo.js";
|
|
2
2
|
export { feishuPlugin, feishuSetupAdapter, feishuSetupWizard };
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/feishu",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.7.1-beta.1",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/feishu",
|
|
9
|
-
"version": "2026.
|
|
9
|
+
"version": "2026.7.1-beta.1",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@larksuiteoapi/node-sdk": "1.66.0",
|
|
12
12
|
"typebox": "1.1.39",
|
|
13
13
|
"zod": "4.4.3"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"openclaw": ">=2026.
|
|
16
|
+
"openclaw": ">=2026.7.1-beta.1"
|
|
17
17
|
},
|
|
18
18
|
"peerDependenciesMeta": {
|
|
19
19
|
"openclaw": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/feishu",
|
|
3
|
-
"version": "2026.
|
|
3
|
+
"version": "2026.7.1-beta.1",
|
|
4
4
|
"description": "OpenClaw Feishu/Lark channel plugin for chats and workplace tools (community maintained by @m1heng).",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"zod": "4.4.3"
|
|
14
14
|
},
|
|
15
15
|
"peerDependencies": {
|
|
16
|
-
"openclaw": ">=2026.
|
|
16
|
+
"openclaw": ">=2026.7.1-beta.1"
|
|
17
17
|
},
|
|
18
18
|
"peerDependenciesMeta": {
|
|
19
19
|
"openclaw": {
|
|
@@ -47,10 +47,10 @@
|
|
|
47
47
|
"minHostVersion": ">=2026.5.29"
|
|
48
48
|
},
|
|
49
49
|
"compat": {
|
|
50
|
-
"pluginApi": ">=2026.
|
|
50
|
+
"pluginApi": ">=2026.7.1-beta.1"
|
|
51
51
|
},
|
|
52
52
|
"build": {
|
|
53
|
-
"openclawVersion": "2026.
|
|
53
|
+
"openclawVersion": "2026.7.1-beta.1"
|
|
54
54
|
},
|
|
55
55
|
"release": {
|
|
56
56
|
"publishToClawHub": true,
|