mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-30 23:32:36 +00:00
105 lines
3.4 KiB
TypeScript
105 lines
3.4 KiB
TypeScript
import { readSqliteSessionRoutingInfo } from "../config/sessions/session-entries.sqlite.js";
|
|
import { resolveAgentIdFromSessionKey } from "../routing/session-key.js";
|
|
import { parseRawSessionConversationRef } from "../sessions/session-key-utils.js";
|
|
import { normalizeOptionalString } from "../shared/string-coerce.js";
|
|
import type { PluginHookAgentContext } from "./hook-types.js";
|
|
|
|
const TARGET_PREFIXES = new Set(["channel", "chat", "direct", "dm", "group", "thread", "user"]);
|
|
|
|
function normalizeKey(value: string | undefined): string {
|
|
return (value ?? "").trim().toLowerCase();
|
|
}
|
|
|
|
function stripConversationPrefix(
|
|
value: string | undefined,
|
|
...providers: Array<string | undefined>
|
|
): string | undefined {
|
|
const text = normalizeOptionalString(value);
|
|
if (!text) {
|
|
return undefined;
|
|
}
|
|
|
|
const separatorIndex = text.indexOf(":");
|
|
if (separatorIndex === -1) {
|
|
return text;
|
|
}
|
|
|
|
const prefix = normalizeKey(text.slice(0, separatorIndex));
|
|
const suffix = normalizeOptionalString(text.slice(separatorIndex + 1));
|
|
if (!suffix) {
|
|
return text;
|
|
}
|
|
if (
|
|
TARGET_PREFIXES.has(prefix) ||
|
|
providers.some((provider) => prefix === normalizeKey(provider))
|
|
) {
|
|
return suffix;
|
|
}
|
|
return text;
|
|
}
|
|
|
|
function readHookSessionConversationPeerId(sessionKey: string | null | undefined) {
|
|
const normalized = normalizeOptionalString(sessionKey);
|
|
if (!normalized) {
|
|
return undefined;
|
|
}
|
|
try {
|
|
const agentId = resolveAgentIdFromSessionKey(normalized);
|
|
return readSqliteSessionRoutingInfo({ agentId, sessionKey: normalized })?.conversationPeerId;
|
|
} catch {
|
|
return undefined;
|
|
}
|
|
}
|
|
|
|
export function resolveAgentHookChannelId(params: {
|
|
sessionKey?: string | null;
|
|
messageChannel?: string | null;
|
|
messageProvider?: string | null;
|
|
currentChannelId?: string | null;
|
|
messageTo?: string | null;
|
|
}): string | undefined {
|
|
const provider = normalizeOptionalString(params.messageProvider);
|
|
const messageChannel = normalizeOptionalString(params.messageChannel);
|
|
const parsed = parseRawSessionConversationRef(params.sessionKey);
|
|
if (parsed?.rawId) {
|
|
return parsed.rawId;
|
|
}
|
|
const typedConversationPeerId = readHookSessionConversationPeerId(params.sessionKey);
|
|
if (typedConversationPeerId) {
|
|
return (
|
|
stripConversationPrefix(typedConversationPeerId, provider, messageChannel) ??
|
|
typedConversationPeerId
|
|
);
|
|
}
|
|
|
|
const metadataChannel =
|
|
stripConversationPrefix(params.currentChannelId ?? undefined, provider, messageChannel) ??
|
|
stripConversationPrefix(params.messageTo ?? undefined, provider, messageChannel);
|
|
if (metadataChannel && normalizeKey(metadataChannel) !== normalizeKey(provider)) {
|
|
return metadataChannel;
|
|
}
|
|
|
|
const strippedMessageChannel = stripConversationPrefix(
|
|
params.messageChannel ?? undefined,
|
|
provider,
|
|
messageChannel,
|
|
);
|
|
if (strippedMessageChannel && normalizeKey(strippedMessageChannel) !== normalizeKey(provider)) {
|
|
return strippedMessageChannel;
|
|
}
|
|
return messageChannel ?? provider;
|
|
}
|
|
|
|
export function buildAgentHookContextChannelFields(params: {
|
|
sessionKey?: string | null;
|
|
messageChannel?: string | null;
|
|
messageProvider?: string | null;
|
|
currentChannelId?: string | null;
|
|
messageTo?: string | null;
|
|
}): Pick<PluginHookAgentContext, "channelId" | "messageProvider"> {
|
|
return {
|
|
messageProvider: normalizeOptionalString(params.messageProvider),
|
|
channelId: resolveAgentHookChannelId(params),
|
|
};
|
|
}
|