openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
55 lines (54 loc) • 2.87 kB
JavaScript
import { i as truncateWithMarker } from "./utf16-slice-D_ngcYKd.mjs";
import { n as resolvePromptHistoryLimit } from "./history-limit-CbktwEI_.mjs";
import { n as markInboundContextLabel } from "./inbound-context-marker-DDxVZisx.mjs";
import { i as normalizeInboundTextNewlines } from "./inbound-context-jAt0CAb-.mjs";
//#region src/auto-reply/reply/channel-prompt-context.ts
/** Appends channel-supplied prompt context to the user-role body under a marked label. */
/**
* The fixed marker lets strippers recognize OpenClaw-injected context; it is not
* a trust guardrail. Trust guidance travels with each entry instead
* (`buildChannelMetadata` wraps entries in `wrapExternalContent`, whose SECURITY
* NOTICE carries the do-not-obey clause).
*/
function appendChannelPromptContext(base, channelPromptContext) {
if (!Array.isArray(channelPromptContext) || channelPromptContext.length === 0) return base;
const entries = channelPromptContext.map((entry) => normalizeInboundTextNewlines(entry)).filter((entry) => Boolean(entry));
if (entries.length === 0) return base;
return [base, [markInboundContextLabel("Context:"), ...entries].join("\n")].filter(Boolean).join("\n\n");
}
const MAX_CONTEXT_JSON_STRING_CHARS = 2e3;
function neutralizeMarkdownFences(value) {
return value.replaceAll("```", "```");
}
function sanitizeContextJsonValue(value) {
if (typeof value === "string") return neutralizeMarkdownFences(truncateWithMarker(value, MAX_CONTEXT_JSON_STRING_CHARS, {
marker: "…[truncated]",
reserve: 14,
trimEnd: true
}));
if (Array.isArray(value)) return value.map(sanitizeContextJsonValue);
if (!value || typeof value !== "object") return value;
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeContextJsonValue(entry)]));
}
function formatContextJsonBlock(label, payload) {
return [
label,
"```json",
JSON.stringify(sanitizeContextJsonValue(payload)),
"```"
].join("\n");
}
/** Preserve a platform-selected window; legacy pending buffers keep their defensive tail cap. */
function selectInboundHistoryContext(ctx) {
const history = Array.isArray(ctx.InboundHistory) ? ctx.InboundHistory : [];
const recent = ctx.SessionTranscriptContext?.historyKind === "recent";
const configuredLimit = ctx.SessionTranscriptContext?.historyLimit;
const limit = recent && typeof configuredLimit === "number" && Number.isSafeInteger(configuredLimit) && configuredLimit >= 0 ? resolvePromptHistoryLimit(configuredLimit, 20) : 20;
return {
boundedHistory: limit > 0 ? history.slice(-limit) : [],
historyLabel: recent ? "Recent chat history:" : "Chat history since last reply:",
truncated: history.length > limit
};
}
//#endregion
export { selectInboundHistoryContext as a, neutralizeMarkdownFences as i, appendChannelPromptContext as n, formatContextJsonBlock as r, MAX_CONTEXT_JSON_STRING_CHARS as t };