openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
154 lines (153 loc) • 6.43 kB
JavaScript
import { c as normalizeOptionalLowercaseString, l as normalizeOptionalString } from "./string-coerce-CIXf7egm.js";
import { m as normalizeUniqueSingleOrTrimmedStringList } from "./string-normalization-DsCfAx8q.js";
import { A as parseRawSessionConversationRef, M as parseThreadSessionSuffix } from "./session-key-BnWWjqNc.js";
import { i as normalizeChatChannelId } from "./ids-BVZRYG0I.js";
import { o as getRuntimeConfigSnapshot } from "./runtime-snapshot-BaQikjTR.js";
import "./registry-COqNvmCg.js";
import { a as tryLoadActivatedBundledPluginPublicSurfaceModuleSync } from "./facade-runtime-BjmVS_9G.js";
import { a as normalizeChannelId, n as getLoadedChannelPlugin } from "./registry-Cz6cv4VC.js";
//#region src/channels/plugins/session-conversation.ts
/**
* Session conversation key helpers.
*
* Resolves threaded channel session keys through plugin hooks and generic parsing.
*/
const SESSION_KEY_API_ARTIFACT_BASENAME = "session-key-api.js";
function normalizeResolvedChannel(channel) {
return normalizeChannelId(channel) ?? normalizeChatChannelId(channel) ?? normalizeOptionalLowercaseString(channel) ?? "";
}
function getMessagingAdapter(channel) {
const normalizedChannel = normalizeResolvedChannel(channel);
try {
return getLoadedChannelPlugin(normalizedChannel)?.messaging;
} catch {
return;
}
}
function buildGenericConversationResolution(rawId) {
const trimmed = rawId.trim();
if (!trimmed) return null;
const parsed = parseThreadSessionSuffix(trimmed);
const id = (parsed.baseSessionKey ?? trimmed).trim();
if (!id) return null;
return {
id,
threadId: parsed.threadId,
baseConversationId: id,
parentConversationCandidates: normalizeUniqueSingleOrTrimmedStringList(parsed.threadId ? [parsed.baseSessionKey] : [])
};
}
function normalizeSessionConversationResolution(resolved) {
if (!resolved?.id?.trim()) return null;
return {
id: resolved.id.trim(),
threadId: normalizeOptionalString(resolved.threadId),
baseConversationId: normalizeOptionalString(resolved.baseConversationId) ?? normalizeUniqueSingleOrTrimmedStringList(resolved.parentConversationCandidates ?? []).at(-1) ?? resolved.id.trim(),
parentConversationCandidates: normalizeUniqueSingleOrTrimmedStringList(resolved.parentConversationCandidates ?? []),
hasExplicitParentConversationCandidates: Object.hasOwn(resolved, "parentConversationCandidates")
};
}
function resolveBundledSessionConversationFallback(params) {
if (isBundledSessionConversationFallbackDisabled(params.channel)) return null;
const dirName = normalizeResolvedChannel(params.channel);
let loaded;
try {
loaded = tryLoadActivatedBundledPluginPublicSurfaceModuleSync({
dirName,
artifactBasename: SESSION_KEY_API_ARTIFACT_BASENAME
});
} catch {
return null;
}
const resolveSessionConversationLocal = loaded?.resolveSessionConversation;
if (typeof resolveSessionConversationLocal !== "function") return null;
return normalizeSessionConversationResolution(resolveSessionConversationLocal({
kind: params.kind,
rawId: params.rawId
}));
}
function isBundledSessionConversationFallbackDisabled(channel) {
const snapshot = getRuntimeConfigSnapshot();
if (!snapshot?.plugins) return false;
if (snapshot.plugins.enabled === false) return true;
const entry = snapshot.plugins.entries?.[normalizeResolvedChannel(channel)];
return Boolean(entry) && typeof entry === "object" && entry.enabled === false;
}
function shouldProbeBundledSessionConversationFallback(rawId) {
return rawId.includes(":");
}
function resolveSessionConversationResolution(params) {
const rawId = params.rawId.trim();
if (!rawId) return null;
const messaging = getMessagingAdapter(params.channel);
const pluginResolved = normalizeSessionConversationResolution(messaging?.resolveSessionConversation?.({
kind: params.kind,
rawId
}));
const shouldTryBundledFallback = params.bundledFallback !== false && !messaging && shouldProbeBundledSessionConversationFallback(rawId);
const resolved = pluginResolved ?? (shouldTryBundledFallback ? resolveBundledSessionConversationFallback({
channel: params.channel,
kind: params.kind,
rawId
}) : null) ?? buildGenericConversationResolution(rawId);
if (!resolved) return null;
const parentConversationCandidates = normalizeUniqueSingleOrTrimmedStringList(pluginResolved?.hasExplicitParentConversationCandidates ? resolved.parentConversationCandidates : messaging?.resolveParentConversationCandidates?.({
kind: params.kind,
rawId
}) ?? resolved.parentConversationCandidates);
const baseConversationId = parentConversationCandidates.at(-1) ?? resolved.baseConversationId ?? resolved.id;
return {
...resolved,
baseConversationId,
parentConversationCandidates
};
}
/**
* Resolves one raw channel conversation id into base/thread conversation metadata.
*/
function resolveSessionConversation(params) {
return resolveSessionConversationResolution(params);
}
function buildBaseSessionKey(raw, id) {
return `${raw.prefix}:${id}`;
}
function resolveSessionConversationRef(sessionKey, opts = {}) {
const raw = parseRawSessionConversationRef(sessionKey);
if (!raw) return null;
const resolved = resolveSessionConversation({
...raw,
bundledFallback: opts.bundledFallback
});
if (!resolved) return null;
return {
channel: normalizeResolvedChannel(raw.channel),
kind: raw.kind,
rawId: raw.rawId,
id: resolved.id,
threadId: resolved.threadId,
baseSessionKey: buildBaseSessionKey(raw, resolved.id),
baseConversationId: resolved.baseConversationId,
parentConversationCandidates: resolved.parentConversationCandidates
};
}
/**
* Resolves thread suffix metadata from a session key, using channel hooks when available.
*/
function resolveSessionThreadInfo(sessionKey, opts = {}) {
const resolved = resolveSessionConversationRef(sessionKey, opts);
if (!resolved) return parseThreadSessionSuffix(sessionKey);
return {
baseSessionKey: resolved.threadId ? resolved.baseSessionKey : normalizeOptionalString(sessionKey),
threadId: resolved.threadId
};
}
/**
* Resolves the parent session key for a threaded child session.
*/
function resolveSessionParentSessionKey(sessionKey) {
const { baseSessionKey, threadId } = resolveSessionThreadInfo(sessionKey);
if (!threadId) return null;
return baseSessionKey ?? null;
}
//#endregion
export { resolveSessionThreadInfo as i, resolveSessionConversationRef as n, resolveSessionParentSessionKey as r, resolveSessionConversation as t };