mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 20:05:46 -06:00
fix(feishu): preserve accepted reply chunks without receipts (#128213)
This commit is contained in:
committed by
GitHub
parent
16a800ebf1
commit
2aa4b694e1
@@ -1638,7 +1638,14 @@ describe("createFeishuReplyDispatcher streaming behavior", () => {
|
||||
.deliver({ text }, { kind: "final" })
|
||||
.catch((caught: unknown) => caught);
|
||||
|
||||
expect(isChannelPartialDeliveryError(error)).toBe(true);
|
||||
expect(error).toMatchObject({
|
||||
code: "CHANNEL_PARTIAL_DELIVERY",
|
||||
deliveryResult: {
|
||||
content: text,
|
||||
messageIds: [],
|
||||
visibleReplySent: true,
|
||||
},
|
||||
});
|
||||
expect(provider).toHaveBeenCalledOnce();
|
||||
await Promise.resolve(options.onError?.(error, { kind: "final" }));
|
||||
expect(result.getVisibleReplyState().visibleReplySent).toBe(true);
|
||||
@@ -1650,6 +1657,50 @@ describe("createFeishuReplyDispatcher streaming behavior", () => {
|
||||
},
|
||||
);
|
||||
|
||||
it.each([
|
||||
{ kind: "text", provider: sendMessageFeishuMock, acceptedBeforeReceiptLoss: 0 },
|
||||
{ kind: "text", provider: sendMessageFeishuMock, acceptedBeforeReceiptLoss: 1 },
|
||||
{ kind: "card", provider: sendStructuredCardFeishuMock, acceptedBeforeReceiptLoss: 0 },
|
||||
{ kind: "card", provider: sendStructuredCardFeishuMock, acceptedBeforeReceiptLoss: 1 },
|
||||
])(
|
||||
"retains accepted $kind chunk content after receipt loss with $acceptedBeforeReceiptLoss prior receipts",
|
||||
async ({ kind, provider, acceptedBeforeReceiptLoss }) => {
|
||||
useNonStreamingAutoAccount();
|
||||
const runtime = getFeishuRuntimeMock();
|
||||
runtime.channel.text.resolveTextChunkLimit.mockReturnValue(6);
|
||||
runtime.channel.text.chunkMarkdownTextWithMode.mockReturnValue(["first", "second", "third"]);
|
||||
|
||||
if (acceptedBeforeReceiptLoss > 0) {
|
||||
provider.mockResolvedValueOnce({ messageId: "om-first" });
|
||||
}
|
||||
provider.mockRejectedValueOnce(
|
||||
createChannelPartialDeliveryError(
|
||||
new Error("Feishu reply failed: no message_id returned"),
|
||||
{
|
||||
messageIds: [],
|
||||
visibleReplySent: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
const { options } = createDispatcherHarness();
|
||||
const text = kind === "card" ? "| first | second |\n| - | - |" : "firstsecondthird";
|
||||
|
||||
const error = await options
|
||||
.deliver({ text }, { kind: "final" })
|
||||
.catch((caught: unknown) => caught);
|
||||
|
||||
expect(error).toMatchObject({
|
||||
code: "CHANNEL_PARTIAL_DELIVERY",
|
||||
deliveryResult: {
|
||||
content: acceptedBeforeReceiptLoss > 0 ? "firstsecond" : "first",
|
||||
messageIds: acceptedBeforeReceiptLoss > 0 ? ["om-first"] : [],
|
||||
visibleReplySent: true,
|
||||
},
|
||||
});
|
||||
expect(provider).toHaveBeenCalledTimes(acceptedBeforeReceiptLoss + 1);
|
||||
},
|
||||
);
|
||||
|
||||
it("retains the finalized streaming card when companion media never dispatches", async () => {
|
||||
const marker = Object.assign(
|
||||
new Error("media load failed", { cause: new Error("blocked local load") }),
|
||||
|
||||
@@ -763,18 +763,22 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP
|
||||
acceptedChunks.push(chunk);
|
||||
markVisibleReplySent();
|
||||
} catch (error: unknown) {
|
||||
if (isChannelPartialDeliveryError(error)) {
|
||||
const acceptedChunk = isChannelPartialDeliveryError(error)
|
||||
? error.deliveryResult
|
||||
: undefined;
|
||||
if (acceptedChunk) {
|
||||
acceptedChunks.push(acceptedChunk.content ?? chunk);
|
||||
markVisibleReplySent();
|
||||
}
|
||||
throw createFeishuPartialReplyDeliveryError(
|
||||
error,
|
||||
createFeishuReplyDeliveryResult({
|
||||
throw createFeishuPartialReplyDeliveryError(error, {
|
||||
...acceptedChunk,
|
||||
...createFeishuReplyDeliveryResult({
|
||||
results,
|
||||
visibleReplySent: results.length > 0,
|
||||
visibleReplySent: results.length > 0 || acceptedChunk !== undefined,
|
||||
content: acceptedChunks.join(""),
|
||||
kind: paramsLocal.useCard ? "card" : "text",
|
||||
}),
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
if (paramsLocal.infoKind === "final") {
|
||||
|
||||
Reference in New Issue
Block a user