openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
89 lines (88 loc) • 3.44 kB
JavaScript
import { r as createLazyRuntimeModule } from "./lazy-runtime-CgCh8H_K.js";
import { t as pruneMapToMaxSize } from "./map-size-CNcWiFKu.js";
import { u as readMediaBuffer } from "./store-Ph57PZ9P.js";
import { f as sessionDeliveryOrigin } from "./delivery-context.shared-CXmRgetN.js";
import { o as resolveInboundMediaReference } from "./media-reference-ZG0ZXjCX.js";
import { a as parseControlUiResourcePath } from "./control-ui-contract-zYW4RcpK.js";
import { i as authorizeControlUiSessionOwnerReadRequestOrReply } from "./http-auth-utils-C3lb4QXY.js";
import { c as sendMethodNotAllowed, v as respondNotFound } from "./http-common-BaZaosnr.js";
import "./http-utils-BHgXp7Zb.js";
import { o as resolveHttpImageRepresentation, s as sendHttpImageResponse, t as HTTP_IMAGE_MAX_BYTES } from "./http-image-response-DUkYrvGx.js";
//#region src/gateway/channel-avatar-http.ts
const CHANNEL_AVATAR_CACHE_MAX_ENTRIES = 128;
const channelAvatarCache = /* @__PURE__ */ new Map();
const getSessionStoreModule = createLazyRuntimeModule(() => import("./session-utils-store-C0Q3cxVd.js"));
function touchChannelAvatarCache(sessionKey, reference) {
const cached = channelAvatarCache.get(sessionKey);
if (!cached || cached.reference !== reference) return;
channelAvatarCache.delete(sessionKey);
channelAvatarCache.set(sessionKey, cached);
return cached.image;
}
async function loadChannelAvatar(sessionKey, reference) {
const cached = touchChannelAvatarCache(sessionKey, reference);
if (cached) return cached;
const resolved = await resolveInboundMediaReference(reference);
if (!resolved) return;
const stored = await readMediaBuffer(resolved.id, "inbound", HTTP_IMAGE_MAX_BYTES);
const image = await resolveHttpImageRepresentation(resolved.id, stored.buffer);
if (!image) return;
channelAvatarCache.delete(sessionKey);
channelAvatarCache.set(sessionKey, {
reference,
image
});
pruneMapToMaxSize(channelAvatarCache, CHANNEL_AVATAR_CACHE_MAX_ENTRIES);
return image;
}
/** Serves the current channel-avatar snapshot for an owner-visible session. */
async function handleChannelAvatarHttpRequest(req, res, opts) {
const pathname = req.url ? new URL(req.url, "http://localhost").pathname : void 0;
const parsed = parseControlUiResourcePath("channelAvatar", pathname, opts.basePath);
if (!parsed.matched) return false;
if (req.method !== "GET" && req.method !== "HEAD") {
sendMethodNotAllowed(res, "GET, HEAD");
return true;
}
if (!await authorizeControlUiSessionOwnerReadRequestOrReply({
req,
res,
auth: opts.auth,
trustedProxies: opts.trustedProxies,
allowRealIpFallback: opts.allowRealIpFallback,
rateLimiter: opts.rateLimiter
})) return true;
if (!parsed.value) {
res.setHeader("cache-control", "no-store");
respondNotFound(res);
return true;
}
let reference;
try {
const { entry } = (await getSessionStoreModule()).loadGatewaySessionEntryReadOnly(parsed.value, { clone: false });
reference = sessionDeliveryOrigin(entry)?.avatar;
} catch {}
if (!reference) {
res.setHeader("cache-control", "no-store");
respondNotFound(res);
return true;
}
let image;
try {
image = await loadChannelAvatar(parsed.value, reference);
} catch {}
if (!image) {
res.setHeader("cache-control", "no-store");
respondNotFound(res);
return true;
}
sendHttpImageResponse({
req,
res,
image,
filename: "channel-avatar"
});
return true;
}
//#endregion
export { handleChannelAvatarHttpRequest };