openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
86 lines (85 loc) • 3.99 kB
JavaScript
import { c as normalizeOptionalString } from "./string-coerce-mnp54Vah.js";
import { r as copyReplyPayloadMetadata } from "./reply-payload-CZJ2cgZc.js";
import { t as parseInlineDirectives } from "./directive-tags-Dg-nkHHo.js";
import { a as hasReplyPayloadContent } from "./payload-CZlThETZ.js";
import { r as resolveImplicitCurrentMessageReplyAllowance, t as createReplyToModeFilterForChannel } from "./reply-threading-D1LzTZCY.js";
import "./reply-payloads-dedupe-LA3qXSSO.js";
//#region src/auto-reply/reply/reply-tags.ts
/** Extracts inline reply-target tags from outbound reply text. */
function extractReplyToTag(text, currentMessageId) {
const result = parseInlineDirectives(text, {
currentMessageId,
stripAudioTag: false
});
return {
cleaned: result.text,
replyToId: result.replyToId,
replyToCurrent: result.replyToCurrent,
hasTag: result.hasReplyTag
};
}
//#endregion
//#region src/auto-reply/reply/reply-payloads-base.ts
/** Adds the BTW question banner for channels that only accept plain text bodies. */
function formatBtwTextForExternalDelivery(payload) {
const text = normalizeOptionalString(payload.text);
if (!text) return payload.text;
const question = normalizeOptionalString(payload.btw?.question);
if (!question) return payload.text;
const formatted = `BTW\nQuestion: ${question}\n\n${text}`;
return text === formatted || text.startsWith("BTW\nQuestion:") ? text : formatted;
}
function resolveReplyThreadingForPayload(params) {
const implicitReplyToId = normalizeOptionalString(params.implicitReplyToId);
const currentMessageId = normalizeOptionalString(params.currentMessageId);
const allowImplicitReplyToCurrentMessage = resolveImplicitCurrentMessageReplyAllowance(params.replyToMode, params.replyThreading);
let resolved = params.payload.replyToId || params.payload.replyToCurrent === false || !implicitReplyToId || !allowImplicitReplyToCurrentMessage ? params.payload : copyReplyPayloadMetadata(params.payload, {
...params.payload,
replyToId: implicitReplyToId
});
if (typeof resolved.text === "string" && resolved.text.includes("[[")) {
const { cleaned, replyToId, replyToCurrent, hasTag } = extractReplyToTag(resolved.text, currentMessageId);
resolved = copyReplyPayloadMetadata(resolved, {
...resolved,
text: cleaned ? cleaned : void 0,
replyToId: replyToId ?? resolved.replyToId,
replyToTag: hasTag || resolved.replyToTag,
replyToCurrent: replyToCurrent || resolved.replyToCurrent
});
}
if (resolved.replyToCurrent && !resolved.replyToId && currentMessageId) resolved = copyReplyPayloadMetadata(resolved, {
...resolved,
replyToId: currentMessageId
});
return resolved;
}
/** Applies inline reply tags to a single payload. */
function applyReplyTagsToPayload(payload, currentMessageId) {
return resolveReplyThreadingForPayload({
payload,
currentMessageId
});
}
/** True when a payload has visible or playable content for delivery. */
function isRenderablePayload(payload) {
return hasReplyPayloadContent(payload, { extraContent: payload.audioAsVoice });
}
/** True when a payload should stay internal as reasoning-only output. */
function shouldSuppressReasoningPayload(payload) {
return payload.isReasoning === true;
}
/** Applies threading policy and filters empty payloads before channel delivery. */
function applyReplyThreading(params) {
const { payloads, replyToMode, replyToChannel, currentMessageId, replyThreading } = params;
const applyReplyToMode = createReplyToModeFilterForChannel(replyToMode, replyToChannel);
const implicitReplyToId = normalizeOptionalString(currentMessageId);
return payloads.map((payload) => resolveReplyThreadingForPayload({
payload,
replyToMode,
implicitReplyToId,
currentMessageId,
replyThreading
})).filter(isRenderablePayload).map(applyReplyToMode);
}
//#endregion
export { shouldSuppressReasoningPayload as a, isRenderablePayload as i, applyReplyThreading as n, formatBtwTextForExternalDelivery as r, applyReplyTagsToPayload as t };