@openclaw/feishu 2026.8.2 → 2026.9.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 +119 -171
- package/dist/{channel-BtM7n79m.js → channel-DSYCNah8.js} +9 -159
- package/dist/channel-plugin-api.js +1 -1
- package/dist/{channel.runtime-DmCiCQJE.js → channel.runtime-EfDl2Q8q.js} +14 -18
- package/dist/{chat-Cbr7P_JH.js → chat-CxXaPTuO.js} +2 -2
- package/dist/{client-vJJyfkxI.js → client-DMbIL3UH.js} +1 -5
- package/dist/{monitor-BVYpA9SO.js → monitor-DoMmOfaD.js} +2 -2
- package/dist/{monitor.account-CuOAmGJf.js → monitor.account-WFdlCDhR.js} +165 -177
- package/dist/{probe-Cs1s-qSS.js → probe-D_SatdZl.js} +1 -1
- package/dist/{reply-delivery-result-BIIeISPG.js → reply-delivery-result-CEFTDA3f.js} +183 -81
- package/dist/setup-api.js +1 -1
- package/dist/{subagent-hooks-BnO3ALWB.js → subagent-hooks-Buadpie_.js} +2 -5
- package/dist/subagent-hooks-api.js +1 -1
- package/dist/{targets-BUjQ1TcA.js → targets-BTQCYRZQ.js} +4 -4
- package/package.json +5 -4
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { o as resolveFeishuAccount, s as resolveFeishuRuntimeAccount } from "./accounts-RwSyseKr.js";
|
|
2
|
-
import { i as resolveReceiveIdType } from "./targets-
|
|
3
|
-
import { A as
|
|
2
|
+
import { i as resolveReceiveIdType } from "./targets-BTQCYRZQ.js";
|
|
3
|
+
import { $ as parseCommentContentElements, A as isFeishuBroadcastMention, At as decodeFeishuCardAction, B as deliverCommentThreadText, D as sendMessageFeishu, E as sendCardFeishu, Et as resolveFeishuChatType, L as buildFeishuMediaFallbackText, M as isFeishuGroupChatType, N as parseInteractiveCardContent, O as sendStructuredCardFeishu, Ot as buildFeishuCardActionTextFallback, P as parsePostContent, R as resolveFeishuIdentityEmoji, S as chunkFeishuCardMarkdown, St as resolveFeishuGroupSenderActivationIngressAccess, T as listFeishuThreadMessages, Tt as normalizeFeishuChatType$2, X as encodeQuery, Y as createCommentTypingReactionLifecycle, Z as extractReplyText, _ as resolveFeishuRichReply, _t as hasExplicitFeishuGroupConfig, at as resolveFeishuCardTemplate, bt as resolveFeishuGroupConfig, ct as materializeFeishuPostMarkdownSoftBreaks, et as requestFeishuApi, g as renderFeishuReplyPayload, i as noVisibleFeishuReplyDelivery, j as isMentionForwardRequest, k as extractMentionTargets, kt as createFeishuCardInteractionEnvelope, l as buildFeishuPresentationFallback, n as createFeishuReplyDeliveryResult, nt as normalizeCommentFileType, r as mergeFeishuReplyDeliveryResults, st as chunkFeishuPostMarkdown, t as createFeishuPartialReplyDeliveryError, tt as buildFeishuCommentTarget, u as consumeFeishuPresentationFallbackMarker, v as saveMessageResourceFeishu, vt as normalizeFeishuAllowEntry, w as getMessageFeishu, wt as resolveFeishuReplyPolicy, x as shouldSuppressFeishuTextForVoiceMedia, xt as resolveFeishuGroupConversationIngressAccess, y as sendMediaFeishu, yt as resolveFeishuDmIngressAccess } from "./reply-delivery-result-CEFTDA3f.js";
|
|
4
4
|
import { a as normalizeFeishuWebhookPath, o as normalizeFeishuExternalKey } from "./doctor-contract-CQAuBotF.js";
|
|
5
5
|
import { o as resolveConfiguredFeishuGroupSessionScope, t as buildFeishuConversationId } from "./conversation-id-VYgGQ-GX.js";
|
|
6
|
-
import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient, s as resolveConfiguredHttpTimeoutMs } from "./client-
|
|
6
|
+
import { a as getFeishuUserAgent, i as createFeishuWSClient, n as createEventDispatcher, r as createFeishuClient, s as resolveConfiguredHttpTimeoutMs } from "./client-DMbIL3UH.js";
|
|
7
7
|
import { t as getFeishuRuntime } from "./runtime-C5JxBWZp.js";
|
|
8
|
-
import { r as getChatInfo } from "./chat-
|
|
8
|
+
import { r as getChatInfo } from "./chat-CxXaPTuO.js";
|
|
9
9
|
import { t as createFeishuThreadBindingManager } from "./thread-bindings-BiL1wGqK.js";
|
|
10
10
|
import { evaluateSupplementalContextVisibility, normalizeAgentId as normalizeAgentId$1, resolveChannelContextVisibilityMode } from "./runtime-api.js";
|
|
11
11
|
import { t as readFeishuJsonResponse } from "./json-response-DXajw_FU.js";
|
|
12
|
-
import { a as waitForAbortableDelay, i as raceWithTimeoutAndAbort } from "./probe-
|
|
13
|
-
import { t as fetchBotIdentityForMonitor } from "./monitor-
|
|
12
|
+
import { a as waitForAbortableDelay, i as raceWithTimeoutAndAbort } from "./probe-D_SatdZl.js";
|
|
13
|
+
import { t as fetchBotIdentityForMonitor } from "./monitor-DoMmOfaD.js";
|
|
14
14
|
import { resolveAgentConfig } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
15
15
|
import { DEFAULT_INGRESS_ADOPTION_STALL_MS, bindIngressLifecycleToReplyOptions, createChannelIngressError, createChannelIngressMonitor, createChannelMessageReplyPipeline, createReplyPrefixContext, formatChannelProgressDraftLineForEntry, isChannelProgressDraftWorkToolName, resolveAgentOutboundIdentity, resolveChannelPreviewStreamMode, resolveChannelStreamingBlockEnabled } from "openclaw/plugin-sdk/channel-outbound";
|
|
16
16
|
import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pairing";
|
|
@@ -1620,21 +1620,10 @@ var FeishuStreamingSession = class {
|
|
|
1620
1620
|
if (finalWriteError !== void 0 || closeError !== void 0) throw new FeishuStreamingFinalizationError(finalWriteError !== void 0 && closeError !== void 0 ? new AggregateError([finalWriteError, closeError], "Feishu streaming card finalization failed") : finalWriteError ?? closeError, result);
|
|
1621
1621
|
return result;
|
|
1622
1622
|
}
|
|
1623
|
-
async close(finalText, options) {
|
|
1624
|
-
try {
|
|
1625
|
-
return (await this.closeWithResult(finalText, options)).visibleReplySent;
|
|
1626
|
-
} catch (error) {
|
|
1627
|
-
if (error instanceof FeishuStreamingFinalizationError) return error.result.visibleReplySent;
|
|
1628
|
-
throw error;
|
|
1629
|
-
}
|
|
1630
|
-
}
|
|
1631
1623
|
async discard() {
|
|
1632
|
-
if (!this.state || this.closed) return;
|
|
1624
|
+
if (!this.state || this.closed) return { visibleReplySent: false };
|
|
1633
1625
|
const { cardId, messageId } = this.state;
|
|
1634
|
-
if (!messageId)
|
|
1635
|
-
await this.close("");
|
|
1636
|
-
return;
|
|
1637
|
-
}
|
|
1626
|
+
if (!messageId) return this.closeWithResult("");
|
|
1638
1627
|
this.closed = true;
|
|
1639
1628
|
this.clearFlushTimer();
|
|
1640
1629
|
await this.queue;
|
|
@@ -1644,10 +1633,11 @@ var FeishuStreamingSession = class {
|
|
|
1644
1633
|
this.state = null;
|
|
1645
1634
|
this.pendingText = null;
|
|
1646
1635
|
this.log?.(`Discarded streaming card: cardId=${cardId}`);
|
|
1636
|
+
return { visibleReplySent: false };
|
|
1647
1637
|
} catch (error) {
|
|
1648
1638
|
this.log?.(`Discard failed: ${String(error)}`);
|
|
1649
1639
|
this.closed = false;
|
|
1650
|
-
|
|
1640
|
+
return this.closeWithResult("");
|
|
1651
1641
|
}
|
|
1652
1642
|
}
|
|
1653
1643
|
isActive() {
|
|
@@ -1905,9 +1895,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
1905
1895
|
let activeStreamingGeneration;
|
|
1906
1896
|
let inFlightStreamingClose;
|
|
1907
1897
|
let visibleReplySent = false;
|
|
1908
|
-
let
|
|
1909
|
-
let skippedFinalAssistantMessageIndex;
|
|
1910
|
-
let preparedDeliveryAssistantMessageIndex;
|
|
1898
|
+
let replyOutcome;
|
|
1911
1899
|
let idleSideEffectsPromise = Promise.resolve();
|
|
1912
1900
|
let activeIdleSideEffectsPromise = null;
|
|
1913
1901
|
let idleRequestedForReply = false;
|
|
@@ -2007,97 +1995,86 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2007
1995
|
lastSnapshotTextLength = 0;
|
|
2008
1996
|
hasStreamingFinalText = false;
|
|
2009
1997
|
};
|
|
2010
|
-
const rememberClosedStreamingSettlement = (generation, content, result, error) => {
|
|
2011
|
-
if (generation === void 0 || !content) return;
|
|
1998
|
+
const rememberClosedStreamingSettlement = (generation, content, result, error, disposition = "closed") => {
|
|
1999
|
+
if (generation === void 0 || !content && disposition === "closed") return;
|
|
2012
2000
|
closedStreamingSettlements.set(generation, {
|
|
2001
|
+
disposition,
|
|
2013
2002
|
result,
|
|
2014
2003
|
content,
|
|
2015
2004
|
...error === void 0 ? {} : { error }
|
|
2016
2005
|
});
|
|
2017
2006
|
};
|
|
2018
|
-
const performStreamingClose = async () => {
|
|
2007
|
+
const performStreamingClose = async (disposition) => {
|
|
2019
2008
|
const streamingToClose = streaming;
|
|
2020
2009
|
const generationToClose = activeStreamingGeneration;
|
|
2021
2010
|
const startPromiseToClose = streamingStartPromise;
|
|
2022
2011
|
const updateQueueToClose = partialUpdateQueue;
|
|
2023
2012
|
const finalizedAnswerText = streamText;
|
|
2024
2013
|
const finalizedReasoningText = reasoningText;
|
|
2014
|
+
const outcome = {
|
|
2015
|
+
disposition,
|
|
2016
|
+
...generationToClose === void 0 ? {} : { generation: generationToClose }
|
|
2017
|
+
};
|
|
2025
2018
|
if (generationToClose !== void 0 && activeStreamingGeneration === generationToClose) activeStreamingGeneration = void 0;
|
|
2026
2019
|
try {
|
|
2027
2020
|
if (startPromiseToClose) await startPromiseToClose;
|
|
2028
2021
|
await updateQueueToClose;
|
|
2022
|
+
let result = noVisibleFeishuReplyDelivery;
|
|
2023
|
+
let finalizationError;
|
|
2029
2024
|
if (streamingToClose?.isActive()) {
|
|
2030
2025
|
statusLine = "";
|
|
2031
2026
|
const text = buildCombinedStreamText(finalizedReasoningText, finalizedAnswerText);
|
|
2032
|
-
const finalNote = resolveCardNote(agentId, identity, responsePrefixContextProvider());
|
|
2033
2027
|
let closed;
|
|
2034
2028
|
try {
|
|
2035
|
-
closed = await streamingToClose.
|
|
2029
|
+
if (disposition === "discarded") closed = await streamingToClose.discard();
|
|
2030
|
+
else {
|
|
2031
|
+
const finalNote = resolveCardNote(agentId, identity, responsePrefixContextProvider());
|
|
2032
|
+
closed = await streamingToClose.closeWithResult(text, { note: finalNote });
|
|
2033
|
+
}
|
|
2036
2034
|
} catch (error) {
|
|
2037
2035
|
if (!(error instanceof FeishuStreamingFinalizationError)) throw error;
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
visibleReplySent: error.result.visibleReplySent,
|
|
2041
|
-
content: error.result.content,
|
|
2042
|
-
kind: "card"
|
|
2043
|
-
});
|
|
2044
|
-
if (failedResult.visibleReplySent) markVisibleReplySent();
|
|
2045
|
-
if (failedResult.visibleReplySent && finalizedAnswerText) {
|
|
2046
|
-
const partialError = createFeishuPartialReplyDeliveryError(error.cause ?? error, failedResult);
|
|
2047
|
-
if (failedResult.content === text) deliveredFinalTexts.add(finalizedAnswerText);
|
|
2048
|
-
rememberClosedStreamingSettlement(generationToClose, finalizedAnswerText, failedResult, partialError);
|
|
2049
|
-
return {
|
|
2050
|
-
result: failedResult,
|
|
2051
|
-
...generationToClose === void 0 ? {} : { generation: generationToClose },
|
|
2052
|
-
error: partialError
|
|
2053
|
-
};
|
|
2054
|
-
}
|
|
2055
|
-
rememberClosedStreamingSettlement(generationToClose, finalizedAnswerText, failedResult, error);
|
|
2056
|
-
return {
|
|
2057
|
-
result: failedResult,
|
|
2058
|
-
...generationToClose === void 0 ? {} : { generation: generationToClose },
|
|
2059
|
-
error
|
|
2060
|
-
};
|
|
2036
|
+
closed = error.result;
|
|
2037
|
+
finalizationError = error;
|
|
2061
2038
|
}
|
|
2062
|
-
|
|
2039
|
+
result = createFeishuReplyDeliveryResult({
|
|
2063
2040
|
results: [closed],
|
|
2064
2041
|
visibleReplySent: closed.visibleReplySent,
|
|
2065
2042
|
content: closed.content,
|
|
2066
2043
|
kind: "card"
|
|
2067
2044
|
});
|
|
2068
2045
|
if (result.visibleReplySent) markVisibleReplySent();
|
|
2069
|
-
if (result.visibleReplySent && finalizedAnswerText)
|
|
2070
|
-
|
|
2071
|
-
rememberClosedStreamingSettlement(generationToClose, finalizedAnswerText, result);
|
|
2072
|
-
}
|
|
2073
|
-
return {
|
|
2074
|
-
result,
|
|
2075
|
-
...generationToClose === void 0 ? {} : { generation: generationToClose }
|
|
2076
|
-
};
|
|
2046
|
+
if (disposition === "closed" && result.visibleReplySent && finalizedAnswerText && (finalizationError === void 0 || result.content === text)) deliveredFinalTexts.add(finalizedAnswerText);
|
|
2047
|
+
if (finalizationError instanceof FeishuStreamingFinalizationError && result.visibleReplySent) finalizationError = createFeishuPartialReplyDeliveryError(finalizationError.cause ?? finalizationError, result);
|
|
2077
2048
|
}
|
|
2049
|
+
if (disposition === "discarded" || finalizationError !== void 0 || result.visibleReplySent && finalizedAnswerText) rememberClosedStreamingSettlement(generationToClose, finalizedAnswerText, result, finalizationError, disposition);
|
|
2078
2050
|
return {
|
|
2079
|
-
|
|
2080
|
-
|
|
2051
|
+
...outcome,
|
|
2052
|
+
result,
|
|
2053
|
+
...finalizationError === void 0 ? {} : { error: finalizationError }
|
|
2081
2054
|
};
|
|
2082
2055
|
} catch (error) {
|
|
2056
|
+
if (disposition === "discarded") rememberClosedStreamingSettlement(generationToClose, finalizedAnswerText, noVisibleFeishuReplyDelivery, error, disposition);
|
|
2083
2057
|
return {
|
|
2058
|
+
...outcome,
|
|
2084
2059
|
result: noVisibleFeishuReplyDelivery,
|
|
2085
|
-
...generationToClose === void 0 ? {} : { generation: generationToClose },
|
|
2086
2060
|
error
|
|
2087
2061
|
};
|
|
2088
2062
|
} finally {
|
|
2089
2063
|
if (streaming === streamingToClose) resetStreamingState();
|
|
2090
2064
|
}
|
|
2091
2065
|
};
|
|
2092
|
-
const closeStreaming = () => {
|
|
2066
|
+
const closeStreaming = (disposition = "closed") => {
|
|
2067
|
+
const session = streaming;
|
|
2093
2068
|
const generation = activeStreamingGeneration;
|
|
2094
|
-
if (
|
|
2069
|
+
if (session && inFlightStreamingClose?.session === session) return inFlightStreamingClose.promise;
|
|
2095
2070
|
const content = streamText;
|
|
2096
|
-
const closePromise = performStreamingClose();
|
|
2097
|
-
if (generation !== void 0) {
|
|
2071
|
+
const closePromise = performStreamingClose(disposition);
|
|
2072
|
+
if (session && generation !== void 0) {
|
|
2098
2073
|
const closing = {
|
|
2074
|
+
session,
|
|
2099
2075
|
generation,
|
|
2100
2076
|
content,
|
|
2077
|
+
disposition,
|
|
2101
2078
|
promise: closePromise
|
|
2102
2079
|
};
|
|
2103
2080
|
inFlightStreamingClose = closing;
|
|
@@ -2129,13 +2106,12 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2129
2106
|
};
|
|
2130
2107
|
};
|
|
2131
2108
|
const discardStreamingPreview = async () => {
|
|
2132
|
-
|
|
2133
|
-
if (streamingStartPromise) await streamingStartPromise;
|
|
2134
|
-
await partialUpdateQueue;
|
|
2135
|
-
if (streaming?.isActive()) await streaming.discard();
|
|
2136
|
-
} finally {
|
|
2109
|
+
if (streaming && inFlightStreamingClose?.session === streaming && inFlightStreamingClose.disposition === "closed") {
|
|
2137
2110
|
resetStreamingState();
|
|
2111
|
+
return;
|
|
2138
2112
|
}
|
|
2113
|
+
const outcome = await closeStreaming("discarded");
|
|
2114
|
+
if (outcome.error !== void 0) throw toStringifiedError(outcome.error);
|
|
2139
2115
|
};
|
|
2140
2116
|
const updateStreamingStatusLine = (nextStatusLine, options) => {
|
|
2141
2117
|
statusLine = nextStatusLine;
|
|
@@ -2198,27 +2174,28 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2198
2174
|
kind: paramsLocal.useCard ? "card" : "text"
|
|
2199
2175
|
});
|
|
2200
2176
|
};
|
|
2177
|
+
const sendPostReply = (text, infoKind, firstChunkMentions) => sendChunkedTextReply({
|
|
2178
|
+
text,
|
|
2179
|
+
useCard: false,
|
|
2180
|
+
infoKind,
|
|
2181
|
+
firstChunkMentions,
|
|
2182
|
+
chunkMentions: requiredMentionTargets,
|
|
2183
|
+
sendChunk: ({ chunk, mentions }) => sendMessageFeishu({
|
|
2184
|
+
cfg,
|
|
2185
|
+
to: sendTarget,
|
|
2186
|
+
text: chunk,
|
|
2187
|
+
replyToMessageId: sendReplyToMessageId,
|
|
2188
|
+
replyInThread: effectiveReplyInThread,
|
|
2189
|
+
allowTopLevelReplyFallback,
|
|
2190
|
+
accountId,
|
|
2191
|
+
...mentions ? { mentions } : {}
|
|
2192
|
+
})
|
|
2193
|
+
});
|
|
2201
2194
|
const sendMediaReplies = async (payload, options) => {
|
|
2202
2195
|
const mediaUrls = resolveSendableOutboundReplyParts(payload).mediaUrls;
|
|
2203
2196
|
let sentFallbackText = false;
|
|
2204
2197
|
let degradedVoiceFallbackText;
|
|
2205
2198
|
const results = [];
|
|
2206
|
-
const sendFallbackText = async (text) => await sendChunkedTextReply({
|
|
2207
|
-
text,
|
|
2208
|
-
useCard: false,
|
|
2209
|
-
infoKind: "final",
|
|
2210
|
-
chunkMentions: requiredMentionTargets,
|
|
2211
|
-
sendChunk: async ({ chunk, mentions }) => await sendMessageFeishu({
|
|
2212
|
-
cfg,
|
|
2213
|
-
to: sendTarget,
|
|
2214
|
-
text: chunk,
|
|
2215
|
-
replyToMessageId: sendReplyToMessageId,
|
|
2216
|
-
replyInThread: effectiveReplyInThread,
|
|
2217
|
-
allowTopLevelReplyFallback,
|
|
2218
|
-
accountId,
|
|
2219
|
-
...mentions ? { mentions } : {}
|
|
2220
|
-
})
|
|
2221
|
-
});
|
|
2222
2199
|
try {
|
|
2223
2200
|
await sendMediaWithLeadingCaption({
|
|
2224
2201
|
mediaUrls,
|
|
@@ -2252,12 +2229,12 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2252
2229
|
mediaUrl
|
|
2253
2230
|
});
|
|
2254
2231
|
sentFallbackText = true;
|
|
2255
|
-
results.push(await
|
|
2232
|
+
results.push(await sendPostReply(fallbackText, "final"));
|
|
2256
2233
|
}
|
|
2257
2234
|
});
|
|
2258
2235
|
if (degradedVoiceFallbackText && !sentFallbackText) {
|
|
2259
2236
|
sentFallbackText = true;
|
|
2260
|
-
results.push(await
|
|
2237
|
+
results.push(await sendPostReply(degradedVoiceFallbackText, "final"));
|
|
2261
2238
|
}
|
|
2262
2239
|
} catch (error) {
|
|
2263
2240
|
const partial = isChannelPartialDeliveryError(error) ? error.deliveryResult : void 0;
|
|
@@ -2269,8 +2246,8 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2269
2246
|
const ensureNoVisibleReplyFallback = async (reason) => {
|
|
2270
2247
|
await idleSideEffectsPromise;
|
|
2271
2248
|
if (visibleReplySent) return false;
|
|
2272
|
-
if (
|
|
2273
|
-
params.runtime.log?.(`feishu[${account.accountId}]: no-visible-reply fallback skipped for
|
|
2249
|
+
if (replyOutcome?.kind === "suppressed" || replyOutcome?.kind === "skipped" && replyOutcome.reason === "silent") {
|
|
2250
|
+
params.runtime.log?.(`feishu[${account.accountId}]: no-visible-reply fallback skipped for ${replyOutcome.reason} (${reason})`);
|
|
2274
2251
|
return false;
|
|
2275
2252
|
}
|
|
2276
2253
|
await sendMessageFeishu({
|
|
@@ -2344,10 +2321,17 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2344
2321
|
if (completions.some((completion) => ownsCurrentClose(completion))) markClosedStreamingContentClaimed(closeOutcome.generation);
|
|
2345
2322
|
for (const completion of completions) {
|
|
2346
2323
|
const claimedSettlement = ownsCurrentClose(completion) ? {
|
|
2324
|
+
disposition: closeOutcome.disposition,
|
|
2347
2325
|
result: finalized,
|
|
2348
2326
|
...closeOutcome.error === void 0 ? {} : { error: closeOutcome.error }
|
|
2349
2327
|
} : claimClosedStreamingResult(completion.streamingGeneration, completion.result.content);
|
|
2350
2328
|
const deliveryError = claimedSettlement?.error;
|
|
2329
|
+
if (claimedSettlement?.disposition === "discarded") {
|
|
2330
|
+
const retained = mergeFeishuReplyDeliveryResults([claimedSettlement.result, completion.result], claimedSettlement.result.content ?? "");
|
|
2331
|
+
if (deliveryError !== void 0) completion.reject(createFeishuPartialReplyDeliveryError(deliveryError, retained));
|
|
2332
|
+
else completion.resolve(retained);
|
|
2333
|
+
continue;
|
|
2334
|
+
}
|
|
2351
2335
|
let providerFinalized = claimedSettlement?.result;
|
|
2352
2336
|
try {
|
|
2353
2337
|
providerFinalized = await ensureVisibleStreamingDelivery(providerFinalized, completion.result.content, completion.infoKind);
|
|
@@ -2384,22 +2368,16 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2384
2368
|
let finalized = noVisibleFeishuReplyDelivery;
|
|
2385
2369
|
let finalizationError;
|
|
2386
2370
|
let fallbackPartial;
|
|
2387
|
-
|
|
2388
|
-
if (
|
|
2389
|
-
finalized = claimedSettlement.result;
|
|
2390
|
-
finalizationError = claimedSettlement.error;
|
|
2391
|
-
} else if (paramsLocal.ownerGeneration !== void 0 && inFlightStreamingClose?.generation === paramsLocal.ownerGeneration) {
|
|
2371
|
+
let settlement = claimClosedStreamingResult(paramsLocal.ownerGeneration, paramsLocal.content);
|
|
2372
|
+
if (!settlement && paramsLocal.ownerGeneration !== void 0 && inFlightStreamingClose?.generation === paramsLocal.ownerGeneration) {
|
|
2392
2373
|
const closeOutcome = await inFlightStreamingClose.promise;
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
finalized = closeOutcome.result;
|
|
2399
|
-
finalizationError = closeOutcome.error;
|
|
2400
|
-
}
|
|
2374
|
+
settlement = claimClosedStreamingResult(paramsLocal.ownerGeneration, paramsLocal.content) ?? closeOutcome;
|
|
2375
|
+
} else if (!settlement && paramsLocal.ownerGeneration !== void 0 && activeStreamingGeneration === paramsLocal.ownerGeneration) settlement = await closeStreaming();
|
|
2376
|
+
finalized = settlement?.result ?? finalized;
|
|
2377
|
+
finalizationError = settlement?.error;
|
|
2378
|
+
const discarded = settlement?.disposition === "discarded";
|
|
2401
2379
|
try {
|
|
2402
|
-
finalized = await ensureVisibleStreamingDelivery(finalized, paramsLocal.content, paramsLocal.infoKind) ?? finalized;
|
|
2380
|
+
if (!discarded) finalized = await ensureVisibleStreamingDelivery(finalized, paramsLocal.content, paramsLocal.infoKind) ?? finalized;
|
|
2403
2381
|
} catch (fallbackError) {
|
|
2404
2382
|
fallbackPartial = isChannelPartialDeliveryError(fallbackError) ? fallbackError.deliveryResult : void 0;
|
|
2405
2383
|
const fallbackCause = fallbackPartial && fallbackError instanceof Error ? fallbackError.cause ?? fallbackError : fallbackError;
|
|
@@ -2410,7 +2388,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2410
2388
|
finalized,
|
|
2411
2389
|
...fallbackPartial ? [fallbackPartial] : [],
|
|
2412
2390
|
...mediaPartial ? [mediaPartial] : []
|
|
2413
|
-
], fallbackPartial?.visibleReplySent === true ? fallbackPartial.content : finalized.visibleReplySent === true ? finalized.content : paramsLocal.content);
|
|
2391
|
+
], discarded ? finalized.content ?? "" : fallbackPartial?.visibleReplySent === true ? fallbackPartial.content : finalized.visibleReplySent === true ? finalized.content : paramsLocal.content);
|
|
2414
2392
|
const mediaCause = mediaPartial && paramsLocal.error instanceof Error ? paramsLocal.error.cause ?? paramsLocal.error : paramsLocal.error;
|
|
2415
2393
|
const cause = finalizationError ? new AggregateError([mediaCause, finalizationError instanceof Error ? finalizationError.cause ?? finalizationError : finalizationError], "Feishu reply delivery and streaming finalization failed") : mediaCause;
|
|
2416
2394
|
throw createFeishuPartialReplyDeliveryError(cause, accepted);
|
|
@@ -2426,13 +2404,14 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2426
2404
|
conversationType: chatId.startsWith("oc_") ? "group" : "direct"
|
|
2427
2405
|
},
|
|
2428
2406
|
onSkip: (_payload, info) => {
|
|
2429
|
-
if (info.kind === "final" || info.kind === "block" && info.reason === "silent") {
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2407
|
+
if (replyOutcome?.kind !== "failed" && (info.kind === "final" || info.kind === "block" && info.reason === "silent")) replyOutcome = {
|
|
2408
|
+
kind: "skipped",
|
|
2409
|
+
reason: info.reason,
|
|
2410
|
+
assistantMessageIndex: info.assistantMessageIndex
|
|
2411
|
+
};
|
|
2433
2412
|
},
|
|
2434
2413
|
beforeDeliver: (payload, info) => {
|
|
2435
|
-
|
|
2414
|
+
if (!(replyOutcome?.kind === "skipped" && replyOutcome.reason === "silent" && info.kind !== "final" && replyOutcome.assistantMessageIndex !== void 0 && info.assistantMessageIndex !== void 0 && info.assistantMessageIndex < replyOutcome.assistantMessageIndex) && replyOutcome?.kind !== "failed") replyOutcome = void 0;
|
|
2436
2415
|
return payload;
|
|
2437
2416
|
},
|
|
2438
2417
|
onReplyStart: async () => {
|
|
@@ -2443,9 +2422,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2443
2422
|
sentIndependentBlockText = false;
|
|
2444
2423
|
idleRequestedForReply = false;
|
|
2445
2424
|
visibleReplySent = false;
|
|
2446
|
-
|
|
2447
|
-
skippedFinalAssistantMessageIndex = void 0;
|
|
2448
|
-
preparedDeliveryAssistantMessageIndex = void 0;
|
|
2425
|
+
replyOutcome = void 0;
|
|
2449
2426
|
}
|
|
2450
2427
|
if (previewStreamingEnabled && renderMode === "card") startStreaming();
|
|
2451
2428
|
await Promise.resolve(typingCallbacks?.onReplyStart?.());
|
|
@@ -2456,6 +2433,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2456
2433
|
}
|
|
2457
2434
|
};
|
|
2458
2435
|
const handleDeliveryError = async (error, info) => {
|
|
2436
|
+
if (info.kind === "final") replyOutcome = { kind: "failed" };
|
|
2459
2437
|
if (isChannelPartialDeliveryError(error)) markVisibleReplySent();
|
|
2460
2438
|
params.runtime.error?.(`feishu[${account.accountId}] ${info.kind} reply failed: ${String(error)}`);
|
|
2461
2439
|
await queueIdleSideEffects().catch((cleanupError) => params.runtime.error?.(`feishu[${account.accountId}] reply error cleanup failed: ${String(cleanupError)}`));
|
|
@@ -2464,19 +2442,36 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2464
2442
|
dispatcherOptions,
|
|
2465
2443
|
delivery: {
|
|
2466
2444
|
observeMessageSent: true,
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
skippedFinalAssistantMessageIndex = void 0;
|
|
2445
|
+
onDelivered: (_payload, info, result) => {
|
|
2446
|
+
if (result?.visibleReplySent) {
|
|
2447
|
+
markVisibleReplySent();
|
|
2448
|
+
if (info.kind === "final") replyOutcome = void 0;
|
|
2449
|
+
return;
|
|
2473
2450
|
}
|
|
2474
|
-
const
|
|
2451
|
+
const reason = result?.suppression?.reason;
|
|
2452
|
+
if (info.kind === "final" && replyOutcome?.kind !== "failed" && (reason === "cancelled_by_reply_payload_sending_hook" || reason === "empty_after_reply_payload_sending_hook" || reason === "cancelled_by_message_sending_hook" || reason === "empty_after_message_sending_hook" || reason === "channel_transform")) replyOutcome = {
|
|
2453
|
+
kind: "suppressed",
|
|
2454
|
+
reason
|
|
2455
|
+
};
|
|
2456
|
+
},
|
|
2457
|
+
deliver: async (inputPayload, info) => {
|
|
2458
|
+
const prepared = await renderFeishuReplyPayload(inputPayload, {
|
|
2459
|
+
to: sendTarget,
|
|
2460
|
+
identity,
|
|
2461
|
+
mentions: requiredMentionTargets
|
|
2462
|
+
});
|
|
2463
|
+
const rendered = consumeFeishuPresentationFallbackMarker(prepared.payload);
|
|
2464
|
+
const payload = rendered.payload;
|
|
2465
|
+
const presentationCard = prepared.card;
|
|
2466
|
+
const hasPresentationFallback = rendered.presentationFallback?.hasVisibleContent === true;
|
|
2467
|
+
const hasIndependentPresentation = presentationCard !== void 0 || hasPresentationFallback;
|
|
2468
|
+
const resolvedText = payload.text;
|
|
2469
|
+
const payloadText = payload.isReasoning && resolvedText ? formatReasoningMessage(resolvedText) : resolvedText;
|
|
2475
2470
|
const reply = resolveSendableOutboundReplyParts({
|
|
2476
2471
|
...payload,
|
|
2477
2472
|
text: payloadText
|
|
2478
2473
|
});
|
|
2479
|
-
const text = info?.kind === "final" ? mergeStreamingFinalText(streamText, reply.text, payload.isError === true && hasStreamingFinalText) : reply.text;
|
|
2474
|
+
const text = info?.kind === "final" && !hasIndependentPresentation ? mergeStreamingFinalText(streamText, reply.text, payload.isError === true && hasStreamingFinalText) : reply.text;
|
|
2480
2475
|
const hasText = reply.hasText;
|
|
2481
2476
|
const hasMedia = reply.hasMedia;
|
|
2482
2477
|
const ttsSupplement = getReplyPayloadTtsSupplement(payload);
|
|
@@ -2490,52 +2485,61 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2490
2485
|
const useStaticCard = hasText && (renderMode === "card" || info?.kind === "block" && coreBlockStreamingEnabled && renderMode !== "raw" || renderMode === "auto" && shouldUseCard(text));
|
|
2491
2486
|
const useStreamingCard = hasText && streamingEnabled && !finalTextExceedsStreamingLimit && (info?.kind === "final" || useStaticCard);
|
|
2492
2487
|
const useCard = useStaticCard || useStreamingCard;
|
|
2493
|
-
const skipTextForDuplicateFinal = info?.kind === "final" && hasText && deliveredFinalTexts.has(text);
|
|
2494
|
-
const shouldDeliverText = hasText && !hasVoiceMedia && !skipTextForDuplicateFinal;
|
|
2495
|
-
const shouldDiscardStreamingPreview = info?.kind === "final" && (finalTextExceedsStreamingLimit || hasMedia && (hasVoiceMedia && !shouldDeliverText && !ttsTextAlreadyVisible || skipTextForDuplicateFinal));
|
|
2488
|
+
const skipTextForDuplicateFinal = !hasIndependentPresentation && info?.kind === "final" && hasText && deliveredFinalTexts.has(text);
|
|
2489
|
+
const shouldDeliverText = hasText && (!hasVoiceMedia || hasPresentationFallback) && !skipTextForDuplicateFinal;
|
|
2490
|
+
const shouldDiscardStreamingPreview = info?.kind === "final" && !(hasIndependentPresentation && payload.isError === true && hasStreamingFinalText) && (hasIndependentPresentation || finalTextExceedsStreamingLimit || hasMedia && (hasVoiceMedia && !shouldDeliverText && !ttsTextAlreadyVisible || skipTextForDuplicateFinal));
|
|
2496
2491
|
const priorClosedStreamingSettlement = info?.kind === "final" && hasText && skipTextForDuplicateFinal ? claimClosedStreamingResult(void 0, text) : void 0;
|
|
2497
|
-
if (!shouldDeliverText && !hasMedia) {
|
|
2492
|
+
if (!shouldDeliverText && !hasMedia && !presentationCard) {
|
|
2498
2493
|
if (priorClosedStreamingSettlement?.error !== void 0) throw toStringifiedError(priorClosedStreamingSettlement.error);
|
|
2499
2494
|
return priorClosedStreamingSettlement?.result ?? noVisibleFeishuReplyDelivery;
|
|
2500
2495
|
}
|
|
2501
2496
|
const deliveredResults = priorClosedStreamingSettlement ? [priorClosedStreamingSettlement.result] : [];
|
|
2502
|
-
const
|
|
2497
|
+
const collectDelivery = async (pending, acceptedContent) => {
|
|
2503
2498
|
try {
|
|
2504
|
-
deliveredResults.push(await
|
|
2499
|
+
deliveredResults.push(await pending);
|
|
2505
2500
|
} catch (error) {
|
|
2506
2501
|
const partial = isChannelPartialDeliveryError(error) ? error.deliveryResult : void 0;
|
|
2507
|
-
const accumulated = mergeFeishuReplyDeliveryResults([...deliveredResults, ...partial ? [
|
|
2508
|
-
|
|
2502
|
+
const accumulated = mergeFeishuReplyDeliveryResults([...deliveredResults, ...partial ? [{
|
|
2503
|
+
...partial,
|
|
2504
|
+
content: partial.content ?? acceptedContent
|
|
2505
|
+
}] : []]);
|
|
2506
|
+
throw createFeishuPartialReplyDeliveryError(partial && error instanceof Error ? error.cause ?? error : error, {
|
|
2507
|
+
...accumulated,
|
|
2508
|
+
content: accumulated.content ?? ""
|
|
2509
|
+
});
|
|
2509
2510
|
}
|
|
2510
2511
|
};
|
|
2511
2512
|
if (shouldDiscardStreamingPreview) await discardStreamingPreview();
|
|
2513
|
+
if (presentationCard) {
|
|
2514
|
+
if (hasMedia) await collectDelivery(sendMediaReplies(payload));
|
|
2515
|
+
await collectDelivery(sendCardFeishu({
|
|
2516
|
+
cfg,
|
|
2517
|
+
to: sendTarget,
|
|
2518
|
+
card: presentationCard,
|
|
2519
|
+
replyToMessageId: sendReplyToMessageId,
|
|
2520
|
+
replyInThread: effectiveReplyInThread,
|
|
2521
|
+
allowTopLevelReplyFallback,
|
|
2522
|
+
accountId
|
|
2523
|
+
}).then((result) => createFeishuReplyDeliveryResult({
|
|
2524
|
+
results: [result],
|
|
2525
|
+
visibleReplySent: true,
|
|
2526
|
+
content: resolvedText,
|
|
2527
|
+
kind: "card"
|
|
2528
|
+
})), resolvedText);
|
|
2529
|
+
markVisibleReplySent();
|
|
2530
|
+
return mergeFeishuReplyDeliveryResults(deliveredResults, resolvedText);
|
|
2531
|
+
}
|
|
2512
2532
|
if (shouldDeliverText) {
|
|
2513
|
-
if (info?.kind === "block") {
|
|
2514
|
-
if (
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
useCard: false,
|
|
2520
|
-
infoKind: "block",
|
|
2521
|
-
firstChunkMentions,
|
|
2522
|
-
chunkMentions: requiredMentionTargets,
|
|
2523
|
-
sendChunk: async ({ chunk, mentions }) => await sendMessageFeishu({
|
|
2524
|
-
cfg,
|
|
2525
|
-
to: sendTarget,
|
|
2526
|
-
text: chunk,
|
|
2527
|
-
replyToMessageId: sendReplyToMessageId,
|
|
2528
|
-
replyInThread: effectiveReplyInThread,
|
|
2529
|
-
allowTopLevelReplyFallback,
|
|
2530
|
-
accountId,
|
|
2531
|
-
...mentions ? { mentions } : {}
|
|
2532
|
-
})
|
|
2533
|
-
}));
|
|
2534
|
-
sentIndependentBlockText = true;
|
|
2535
|
-
if (hasMedia) await collectMediaDelivery(payload);
|
|
2536
|
-
}
|
|
2537
|
-
return mergeFeishuReplyDeliveryResults(deliveredResults, text);
|
|
2533
|
+
if (hasPresentationFallback || info?.kind === "block" && !useStreamingCard) {
|
|
2534
|
+
if (hasPresentationFallback || coreBlockStreamingEnabled) {
|
|
2535
|
+
const firstChunkMentions = info?.kind === "final" || info?.kind === "block" && !sentIndependentBlockText ? mentionTargets : void 0;
|
|
2536
|
+
await collectDelivery(sendPostReply(text, info?.kind, firstChunkMentions));
|
|
2537
|
+
if (info?.kind === "block") sentIndependentBlockText = true;
|
|
2538
|
+
if (hasMedia) await collectDelivery(sendMediaReplies(payload));
|
|
2538
2539
|
}
|
|
2540
|
+
return mergeFeishuReplyDeliveryResults(deliveredResults, text);
|
|
2541
|
+
}
|
|
2542
|
+
if (info?.kind === "block") {
|
|
2539
2543
|
startStreaming();
|
|
2540
2544
|
if (streamingStartPromise) await streamingStartPromise;
|
|
2541
2545
|
}
|
|
@@ -2544,7 +2548,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2544
2548
|
if (streamingStartPromise) await streamingStartPromise;
|
|
2545
2549
|
}
|
|
2546
2550
|
const shouldStreamText = info?.kind === "block" || info?.kind === "final";
|
|
2547
|
-
const matchingInFlightClose = info?.kind === "final" && inFlightStreamingClose?.content === text ? inFlightStreamingClose : void 0;
|
|
2551
|
+
const matchingInFlightClose = info?.kind === "final" && inFlightStreamingClose?.disposition === "closed" && inFlightStreamingClose.content === text ? inFlightStreamingClose : void 0;
|
|
2548
2552
|
const ownerGeneration = activeStreamingGeneration ?? matchingInFlightClose?.generation;
|
|
2549
2553
|
if (shouldStreamText && ownerGeneration !== void 0 && (streaming?.isActive() || matchingInFlightClose !== void 0)) {
|
|
2550
2554
|
if (activeStreamingGeneration !== void 0) {
|
|
@@ -2561,7 +2565,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2561
2565
|
}
|
|
2562
2566
|
}
|
|
2563
2567
|
if (hasMedia) try {
|
|
2564
|
-
await
|
|
2568
|
+
await collectDelivery(sendMediaReplies(payload));
|
|
2565
2569
|
} catch (error) {
|
|
2566
2570
|
await throwStreamingDeliveryFailure({
|
|
2567
2571
|
error,
|
|
@@ -2597,26 +2601,10 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2597
2601
|
}));
|
|
2598
2602
|
} else {
|
|
2599
2603
|
const firstChunkMentions = info?.kind === "final" && mentionTargets?.length ? mentionTargets : void 0;
|
|
2600
|
-
deliveredResults.push(await
|
|
2601
|
-
text,
|
|
2602
|
-
useCard: false,
|
|
2603
|
-
infoKind: info?.kind,
|
|
2604
|
-
firstChunkMentions,
|
|
2605
|
-
chunkMentions: requiredMentionTargets,
|
|
2606
|
-
sendChunk: async ({ chunk, mentions }) => await sendMessageFeishu({
|
|
2607
|
-
cfg,
|
|
2608
|
-
to: sendTarget,
|
|
2609
|
-
text: chunk,
|
|
2610
|
-
replyToMessageId: sendReplyToMessageId,
|
|
2611
|
-
replyInThread: effectiveReplyInThread,
|
|
2612
|
-
allowTopLevelReplyFallback,
|
|
2613
|
-
accountId,
|
|
2614
|
-
...mentions ? { mentions } : {}
|
|
2615
|
-
})
|
|
2616
|
-
}));
|
|
2604
|
+
deliveredResults.push(await sendPostReply(text, info?.kind, firstChunkMentions));
|
|
2617
2605
|
}
|
|
2618
2606
|
}
|
|
2619
|
-
if (hasMedia) await
|
|
2607
|
+
if (hasMedia) await collectDelivery(sendMediaReplies(payload, !shouldDeliverText && !ttsTextAlreadyVisible && hasVoiceMedia && hasText ? { fallbackText: text } : void 0));
|
|
2620
2608
|
const deliveredContent = hasVoiceMedia ? deliveredResults.at(-1)?.content ?? text : text;
|
|
2621
2609
|
const result = mergeFeishuReplyDeliveryResults(deliveredResults, deliveredContent);
|
|
2622
2610
|
if (priorClosedStreamingSettlement?.error !== void 0) throw createFeishuPartialReplyDeliveryError(isChannelPartialDeliveryError(priorClosedStreamingSettlement.error) && priorClosedStreamingSettlement.error instanceof Error ? priorClosedStreamingSettlement.error.cause ?? priorClosedStreamingSettlement.error : priorClosedStreamingSettlement.error, result);
|
|
@@ -2666,7 +2654,7 @@ function createFeishuReplyDispatcher(params) {
|
|
|
2666
2654
|
ensureNoVisibleReplyFallback,
|
|
2667
2655
|
getVisibleReplyState: () => ({
|
|
2668
2656
|
visibleReplySent,
|
|
2669
|
-
skippedFinalReason
|
|
2657
|
+
skippedFinalReason: replyOutcome?.kind === "skipped" || replyOutcome?.kind === "suppressed" ? replyOutcome.reason : null
|
|
2670
2658
|
})
|
|
2671
2659
|
};
|
|
2672
2660
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { r as createFeishuClient } from "./client-
|
|
2
|
+
import { r as createFeishuClient } from "./client-DMbIL3UH.js";
|
|
3
3
|
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
4
4
|
import { asDateTimestampMs, resolveExpiresAtMsFromDurationMs, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
5
5
|
import { createHash } from "node:crypto";
|