mirror of
https://github.com/openclaw/openclaw.git
synced 2026-03-22 15:31:07 +00:00
refactor: deduplicate reply payload handling
This commit is contained in:
@@ -5,6 +5,7 @@ import { createReplyPrefixOptions } from "openclaw/plugin-sdk/channel-runtime";
|
||||
import { createTypingCallbacks } from "openclaw/plugin-sdk/channel-runtime";
|
||||
import { resolveStorePath, updateLastRoute } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { resolveAgentOutboundIdentity } from "openclaw/plugin-sdk/infra-runtime";
|
||||
import { resolveSendableOutboundReplyParts } from "openclaw/plugin-sdk/reply-payload";
|
||||
import { dispatchInboundMessage } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { clearHistoryEntriesIfEnabled } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { createReplyDispatcherWithTyping } from "openclaw/plugin-sdk/reply-runtime";
|
||||
@@ -33,7 +34,7 @@ import {
|
||||
import type { PreparedSlackMessage } from "./types.js";
|
||||
|
||||
function hasMedia(payload: ReplyPayload): boolean {
|
||||
return Boolean(payload.mediaUrl) || (payload.mediaUrls?.length ?? 0) > 0;
|
||||
return resolveSendableOutboundReplyParts(payload).hasMedia;
|
||||
}
|
||||
|
||||
export function isSlackStreamingEnabled(params: {
|
||||
@@ -250,17 +251,13 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
|
||||
};
|
||||
|
||||
const deliverWithStreaming = async (payload: ReplyPayload): Promise<void> => {
|
||||
if (
|
||||
streamFailed ||
|
||||
hasMedia(payload) ||
|
||||
readSlackReplyBlocks(payload)?.length ||
|
||||
!payload.text?.trim()
|
||||
) {
|
||||
const reply = resolveSendableOutboundReplyParts(payload);
|
||||
if (streamFailed || reply.hasMedia || readSlackReplyBlocks(payload)?.length || !reply.hasText) {
|
||||
await deliverNormally(payload, streamSession?.threadTs);
|
||||
return;
|
||||
}
|
||||
|
||||
const text = payload.text.trim();
|
||||
const text = reply.trimmedText;
|
||||
let plannedThreadTs: string | undefined;
|
||||
try {
|
||||
if (!streamSession) {
|
||||
@@ -311,16 +308,16 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
|
||||
return;
|
||||
}
|
||||
|
||||
const mediaCount = payload.mediaUrls?.length ?? (payload.mediaUrl ? 1 : 0);
|
||||
const reply = resolveSendableOutboundReplyParts(payload);
|
||||
const slackBlocks = readSlackReplyBlocks(payload);
|
||||
const draftMessageId = draftStream?.messageId();
|
||||
const draftChannelId = draftStream?.channelId();
|
||||
const finalText = payload.text ?? "";
|
||||
const trimmedFinalText = finalText.trim();
|
||||
const finalText = reply.text;
|
||||
const trimmedFinalText = reply.trimmedText;
|
||||
const canFinalizeViaPreviewEdit =
|
||||
previewStreamingEnabled &&
|
||||
streamMode !== "status_final" &&
|
||||
mediaCount === 0 &&
|
||||
!reply.hasMedia &&
|
||||
!payload.isError &&
|
||||
(trimmedFinalText.length > 0 || Boolean(slackBlocks?.length)) &&
|
||||
typeof draftMessageId === "string" &&
|
||||
@@ -361,7 +358,7 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
|
||||
} catch (err) {
|
||||
logVerbose(`slack: status_final completion update failed (${String(err)})`);
|
||||
}
|
||||
} else if (mediaCount > 0) {
|
||||
} else if (reply.hasMedia) {
|
||||
await draftStream?.clear();
|
||||
hasStreamedMessage = false;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import type { MarkdownTableMode } from "openclaw/plugin-sdk/config-runtime";
|
||||
import { deliverTextOrMediaReply } from "openclaw/plugin-sdk/reply-payload";
|
||||
import {
|
||||
deliverTextOrMediaReply,
|
||||
resolveSendableOutboundReplyParts,
|
||||
} from "openclaw/plugin-sdk/reply-payload";
|
||||
import type { ChunkMode } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { chunkMarkdownTextWithMode } from "openclaw/plugin-sdk/reply-runtime";
|
||||
import { createReplyReferencePlanner } from "openclaw/plugin-sdk/reply-runtime";
|
||||
@@ -38,15 +41,14 @@ export async function deliverReplies(params: {
|
||||
// must not force threading.
|
||||
const inlineReplyToId = params.replyToMode === "off" ? undefined : payload.replyToId;
|
||||
const threadTs = inlineReplyToId ?? params.replyThreadTs;
|
||||
const mediaList = payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
const text = payload.text ?? "";
|
||||
const reply = resolveSendableOutboundReplyParts(payload);
|
||||
const slackBlocks = readSlackReplyBlocks(payload);
|
||||
if (!text && mediaList.length === 0 && !slackBlocks?.length) {
|
||||
if (!reply.hasContent && !slackBlocks?.length) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mediaList.length === 0 && slackBlocks?.length) {
|
||||
const trimmed = text.trim();
|
||||
if (!reply.hasMedia && slackBlocks?.length) {
|
||||
const trimmed = reply.trimmedText;
|
||||
if (!trimmed && !slackBlocks?.length) {
|
||||
continue;
|
||||
}
|
||||
@@ -66,17 +68,16 @@ export async function deliverReplies(params: {
|
||||
|
||||
const delivered = await deliverTextOrMediaReply({
|
||||
payload,
|
||||
text,
|
||||
chunkText:
|
||||
mediaList.length === 0
|
||||
? (value) => {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed || isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) {
|
||||
return [];
|
||||
}
|
||||
return [trimmed];
|
||||
text: reply.text,
|
||||
chunkText: !reply.hasMedia
|
||||
? (value) => {
|
||||
const trimmed = value.trim();
|
||||
if (!trimmed || isSilentReplyText(trimmed, SILENT_REPLY_TOKEN)) {
|
||||
return [];
|
||||
}
|
||||
: undefined,
|
||||
return [trimmed];
|
||||
}
|
||||
: undefined,
|
||||
sendText: async (trimmed) => {
|
||||
await sendMessageSlack(params.target, trimmed, {
|
||||
token: params.token,
|
||||
@@ -189,12 +190,12 @@ export async function deliverSlackSlashReplies(params: {
|
||||
const messages: string[] = [];
|
||||
const chunkLimit = Math.min(params.textLimit, 4000);
|
||||
for (const payload of params.replies) {
|
||||
const textRaw = payload.text?.trim() ?? "";
|
||||
const text = textRaw && !isSilentReplyText(textRaw, SILENT_REPLY_TOKEN) ? textRaw : undefined;
|
||||
const mediaList = payload.mediaUrls ?? (payload.mediaUrl ? [payload.mediaUrl] : []);
|
||||
const combined = [text ?? "", ...mediaList.map((url) => url.trim()).filter(Boolean)]
|
||||
.filter(Boolean)
|
||||
.join("\n");
|
||||
const reply = resolveSendableOutboundReplyParts(payload);
|
||||
const text =
|
||||
reply.hasText && !isSilentReplyText(reply.trimmedText, SILENT_REPLY_TOKEN)
|
||||
? reply.trimmedText
|
||||
: undefined;
|
||||
const combined = [text ?? "", ...reply.mediaUrls].filter(Boolean).join("\n");
|
||||
if (!combined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user