openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
91 lines (90 loc) • 4.43 kB
JavaScript
import { l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { i as copyReplyPayloadMetadata, y as setReplyPayloadMetadata } from "./reply-payload-DahKk-7n.js";
import { t as parseInlineDirectives } from "./directive-tags-Wp1S72ap.js";
import { o as hasReplyPayloadContent } from "./payload-DYE7bQ2k.js";
import { i as resolveImplicitCurrentMessageReplyAllowance, n as createReplyToModeFilterForChannel } from "./reply-threading-b8mBrrsZ.js";
import "./reply-payloads-dedupe-Di5U9fOH.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 payload = normalizeOptionalString(params.payload.replyToId) ? setReplyPayloadMetadata(copyReplyPayloadMetadata(params.payload, { ...params.payload }), { replyToIdExplicit: true }) : params.payload;
const implicitReplyToId = normalizeOptionalString(params.implicitReplyToId);
const currentMessageId = normalizeOptionalString(params.currentMessageId);
const allowImplicitReplyToCurrentMessage = resolveImplicitCurrentMessageReplyAllowance(params.replyToMode, params.replyThreading);
let resolved = payload.replyToId || payload.replyToCurrent === false || !implicitReplyToId || !allowImplicitReplyToCurrentMessage ? payload : copyReplyPayloadMetadata(payload, {
...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 || payload.location != null });
}
/** True when a payload should stay internal as reasoning-only output. */
function shouldSuppressReasoningPayload(payload) {
return payload.isReasoning === true;
}
/** Resolves reply targets and filters empty payloads before channel delivery. */
function resolveReplyThreadingPayloads(params) {
const { payloads, replyToMode, currentMessageId, replyThreading } = params;
const implicitReplyToId = normalizeOptionalString(currentMessageId);
return payloads.map((payload) => resolveReplyThreadingForPayload({
payload,
replyToMode,
implicitReplyToId,
currentMessageId,
replyThreading
})).filter(isRenderablePayload);
}
/** Applies threading policy and filters empty payloads before channel delivery. */
function applyReplyThreading(params) {
const applyReplyToMode = createReplyToModeFilterForChannel(params.replyToMode, params.replyToChannel);
return resolveReplyThreadingPayloads(params).map(applyReplyToMode);
}
//#endregion
export { resolveReplyThreadingPayloads as a, isRenderablePayload as i, applyReplyThreading as n, shouldSuppressReasoningPayload as o, formatBtwTextForExternalDelivery as r, applyReplyTagsToPayload as t };