mirror of
https://github.com/moltbot/moltbot.git
synced 2026-05-15 17:05:34 +00:00
refactor: remove runtime legacy session hooks
This commit is contained in:
@@ -13,7 +13,6 @@ export {
|
||||
unsupportedSecretRefSurfacePatterns,
|
||||
collectUnsupportedSecretRefConfigCandidates,
|
||||
} from "./src/security-contract.js";
|
||||
export { deriveLegacySessionChatType } from "./src/session-contract.js";
|
||||
export type {
|
||||
DiscordInteractiveHandlerContext,
|
||||
DiscordInteractiveHandlerRegistration,
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
export function deriveLegacySessionChatType(sessionKey: string): "channel" | undefined {
|
||||
return /^discord:(?:[^:]+:)?guild-[^:]+:channel-[^:]+$/.test(sessionKey) ? "channel" : undefined;
|
||||
}
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
unsupportedSecretRefSurfacePatterns,
|
||||
} from "./security-contract.js";
|
||||
import { discordSecurityAdapter } from "./security.js";
|
||||
import { deriveLegacySessionChatType } from "./session-contract.js";
|
||||
|
||||
const DISCORD_CHANNEL = "discord" as const;
|
||||
|
||||
@@ -160,9 +159,6 @@ export function createDiscordPluginBase(params: {
|
||||
},
|
||||
}),
|
||||
},
|
||||
messaging: {
|
||||
deriveLegacySessionChatType,
|
||||
},
|
||||
security: discordSecurityAdapter,
|
||||
secrets: {
|
||||
secretTargetRegistryEntries,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { whatsappCommandPolicy as whatsappCommandPolicyImpl } from "./src/command-policy.js";
|
||||
import { resolveLegacyGroupSessionKey as resolveLegacyGroupSessionKeyImpl } from "./src/group-session-contract.js";
|
||||
import { resolveGroupSessionKey as resolveGroupSessionKeyImpl } from "./src/group-session-contract.js";
|
||||
import { __testing as whatsappAccessControlTestingImpl } from "./src/inbound/access-control.js";
|
||||
import {
|
||||
isWhatsAppGroupJid as isWhatsAppGroupJidImpl,
|
||||
@@ -10,20 +10,14 @@ export {
|
||||
listWhatsAppDirectoryPeersFromConfig,
|
||||
} from "./src/directory-config.js";
|
||||
import { resolveWhatsAppRuntimeGroupPolicy as resolveWhatsAppRuntimeGroupPolicyImpl } from "./src/runtime-group-policy.js";
|
||||
import {
|
||||
canonicalizeLegacySessionKey as canonicalizeLegacySessionKeyImpl,
|
||||
isLegacyGroupSessionKey as isLegacyGroupSessionKeyImpl,
|
||||
} from "./src/session-contract.js";
|
||||
export {
|
||||
collectUnsupportedSecretRefConfigCandidates,
|
||||
unsupportedSecretRefSurfacePatterns,
|
||||
} from "./src/security-contract.js";
|
||||
|
||||
export const canonicalizeLegacySessionKey = canonicalizeLegacySessionKeyImpl;
|
||||
export const isLegacyGroupSessionKey = isLegacyGroupSessionKeyImpl;
|
||||
export const isWhatsAppGroupJid = isWhatsAppGroupJidImpl;
|
||||
export const normalizeWhatsAppTarget = normalizeWhatsAppTargetImpl;
|
||||
export const resolveLegacyGroupSessionKey = resolveLegacyGroupSessionKeyImpl;
|
||||
export const resolveGroupSessionKey = resolveGroupSessionKeyImpl;
|
||||
export const resolveWhatsAppRuntimeGroupPolicy = resolveWhatsAppRuntimeGroupPolicyImpl;
|
||||
export const whatsappAccessControlTesting = whatsappAccessControlTestingImpl;
|
||||
export const whatsappCommandPolicy = whatsappCommandPolicyImpl;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
|
||||
export function resolveLegacyGroupSessionKey(ctx: { From?: string }): {
|
||||
export function resolveGroupSessionKey(ctx: { From?: string }): {
|
||||
key: string;
|
||||
channel: string;
|
||||
id: string;
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import {
|
||||
canonicalizeLegacySessionKey,
|
||||
deriveLegacySessionChatType,
|
||||
isLegacyGroupSessionKey,
|
||||
} from "./session-contract.js";
|
||||
import { canonicalizeLegacySessionKey, isLegacyGroupSessionKey } from "./session-contract.js";
|
||||
|
||||
describe("whatsapp legacy session contract", () => {
|
||||
it("canonicalizes legacy WhatsApp group keys to channel-qualified agent keys", () => {
|
||||
@@ -20,12 +16,11 @@ describe("whatsapp legacy session contract", () => {
|
||||
|
||||
it("does not claim generic non-WhatsApp group keys", () => {
|
||||
expect(isLegacyGroupSessionKey("group:abc")).toBe(false);
|
||||
expect(deriveLegacySessionChatType("group:abc")).toBeUndefined();
|
||||
expect(canonicalizeLegacySessionKey({ key: "group:abc", agentId: "main" })).toBeNull();
|
||||
});
|
||||
|
||||
it("derives chat type for legacy WhatsApp group keys", () => {
|
||||
expect(deriveLegacySessionChatType("123@g.us")).toBe("group");
|
||||
expect(deriveLegacySessionChatType("whatsapp:123@g.us")).toBe("group");
|
||||
it("identifies legacy WhatsApp group keys for doctor migration", () => {
|
||||
expect(isLegacyGroupSessionKey("123@g.us")).toBe(true);
|
||||
expect(isLegacyGroupSessionKey("whatsapp:123@g.us")).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,10 +28,6 @@ export function isLegacyGroupSessionKey(key: string): boolean {
|
||||
return extractLegacyWhatsAppGroupId(key) !== null;
|
||||
}
|
||||
|
||||
export function deriveLegacySessionChatType(key: string): "group" | undefined {
|
||||
return isLegacyGroupSessionKey(key) ? "group" : undefined;
|
||||
}
|
||||
|
||||
export function canonicalizeLegacySessionKey(params: {
|
||||
key: string;
|
||||
agentId: string;
|
||||
|
||||
@@ -26,17 +26,12 @@ import {
|
||||
import { formatWhatsAppConfigAllowFromEntries } from "./config-accessors.js";
|
||||
import { WhatsAppChannelConfigSchema } from "./config-schema.js";
|
||||
import { whatsappDoctor } from "./doctor.js";
|
||||
import { resolveLegacyGroupSessionKey } from "./group-session-contract.js";
|
||||
import { resolveGroupSessionKey } from "./group-session-contract.js";
|
||||
import {
|
||||
collectUnsupportedSecretRefConfigCandidates,
|
||||
unsupportedSecretRefSurfacePatterns,
|
||||
} from "./security-contract.js";
|
||||
import { applyWhatsAppSecurityConfigFixes } from "./security-fix.js";
|
||||
import {
|
||||
canonicalizeLegacySessionKey,
|
||||
deriveLegacySessionChatType,
|
||||
isLegacyGroupSessionKey,
|
||||
} from "./session-contract.js";
|
||||
|
||||
const WHATSAPP_CHANNEL = "whatsapp" as const;
|
||||
|
||||
@@ -259,11 +254,7 @@ export function createWhatsAppPluginBase(params: {
|
||||
config: base.config!,
|
||||
messaging: {
|
||||
defaultMarkdownTableMode: "bullets",
|
||||
deriveLegacySessionChatType,
|
||||
resolveLegacyGroupSessionKey,
|
||||
isLegacyGroupSessionKey,
|
||||
canonicalizeLegacySessionKey: (params) =>
|
||||
canonicalizeLegacySessionKey({ key: params.key, agentId: params.agentId }),
|
||||
resolveGroupSessionKey,
|
||||
},
|
||||
secrets: {
|
||||
unsupportedSecretRefSurfacePatterns,
|
||||
|
||||
@@ -729,11 +729,7 @@ export function listBundledChannelLegacySessionSurfaces(
|
||||
if (surface) {
|
||||
return [surface];
|
||||
}
|
||||
if (!hasSetupEntryFeature(setupEntry, "legacySessionSurfaces")) {
|
||||
return [];
|
||||
}
|
||||
const plugin = getBundledChannelSetupPluginForRoot(id, rootScope, loadContext);
|
||||
return plugin?.messaging ? [plugin.messaging] : [];
|
||||
return [];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -515,13 +515,7 @@ export type ChannelMessagingAdapter = {
|
||||
sessionKey: string;
|
||||
ctx: MsgContext;
|
||||
}) => string | undefined;
|
||||
deriveLegacySessionChatType?: (sessionKey: string) => "direct" | "group" | "channel" | undefined;
|
||||
isLegacyGroupSessionKey?: (key: string) => boolean;
|
||||
canonicalizeLegacySessionKey?: (params: {
|
||||
key: string;
|
||||
agentId: string;
|
||||
}) => string | null | undefined;
|
||||
resolveLegacyGroupSessionKey?: (ctx: MsgContext) => {
|
||||
resolveGroupSessionKey?: (ctx: MsgContext) => {
|
||||
key: string;
|
||||
channel: string;
|
||||
id: string;
|
||||
|
||||
@@ -11,15 +11,15 @@ import type { GroupKeyResolution } from "./types.js";
|
||||
|
||||
const getGroupSurfaces = () => new Set<string>([...listDeliverableMessageChannels(), "webchat"]);
|
||||
|
||||
type LegacyGroupSessionSurface = {
|
||||
resolveLegacyGroupSessionKey?: (ctx: MsgContext) => GroupKeyResolution | null;
|
||||
type GroupSessionSurface = {
|
||||
resolveGroupSessionKey?: (ctx: MsgContext) => GroupKeyResolution | null;
|
||||
};
|
||||
|
||||
function resolveLegacyGroupSessionKey(ctx: MsgContext): GroupKeyResolution | null {
|
||||
function resolvePluginGroupSessionKey(ctx: MsgContext): GroupKeyResolution | null {
|
||||
for (const plugin of listChannelPlugins()) {
|
||||
const resolved = (
|
||||
plugin.messaging as LegacyGroupSessionSurface | undefined
|
||||
)?.resolveLegacyGroupSessionKey?.(ctx);
|
||||
plugin.messaging as GroupSessionSurface | undefined
|
||||
)?.resolveGroupSessionKey?.(ctx);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
@@ -107,13 +107,13 @@ export function resolveGroupSessionKey(ctx: MsgContext): GroupKeyResolution | nu
|
||||
const normalizedChatType =
|
||||
chatType === "channel" ? "channel" : chatType === "group" ? "group" : undefined;
|
||||
|
||||
const legacyResolution = resolveLegacyGroupSessionKey(ctx);
|
||||
const pluginResolution = resolvePluginGroupSessionKey(ctx);
|
||||
const looksLikeGroup =
|
||||
normalizedChatType === "group" ||
|
||||
normalizedChatType === "channel" ||
|
||||
from.includes(":group:") ||
|
||||
from.includes(":channel:") ||
|
||||
legacyResolution !== null;
|
||||
pluginResolution !== null;
|
||||
if (!looksLikeGroup) {
|
||||
return null;
|
||||
}
|
||||
@@ -124,11 +124,11 @@ export function resolveGroupSessionKey(ctx: MsgContext): GroupKeyResolution | nu
|
||||
const head = normalizeLowercaseStringOrEmpty(parts[0]);
|
||||
const headIsSurface = head ? getGroupSurfaces().has(head) : false;
|
||||
|
||||
if (!headIsSurface && !providerHint && legacyResolution) {
|
||||
return legacyResolution;
|
||||
if (!headIsSurface && !providerHint && pluginResolution) {
|
||||
return pluginResolution;
|
||||
}
|
||||
|
||||
const provider = headIsSurface ? head : (providerHint ?? legacyResolution?.channel);
|
||||
const provider = headIsSurface ? head : (providerHint ?? pluginResolution?.channel);
|
||||
if (!provider) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -3,21 +3,7 @@ import { parseAgentSessionKey } from "./session-key-utils.js";
|
||||
|
||||
export type SessionKeyChatType = "direct" | "group" | "channel" | "unknown";
|
||||
|
||||
function deriveBuiltInLegacySessionChatType(
|
||||
scopedSessionKey: string,
|
||||
): SessionKeyChatType | undefined {
|
||||
if (/^group:[^:]+$/.test(scopedSessionKey)) {
|
||||
return "group";
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function deriveSessionChatTypeFromScopedKey(
|
||||
scopedSessionKey: string,
|
||||
deriveLegacySessionChatTypes: Array<
|
||||
(scopedSessionKey: string) => SessionKeyChatType | undefined
|
||||
> = [],
|
||||
): SessionKeyChatType {
|
||||
export function deriveSessionChatTypeFromScopedKey(scopedSessionKey: string): SessionKeyChatType {
|
||||
const tokens = new Set(scopedSessionKey.split(":").filter(Boolean));
|
||||
if (tokens.has("group")) {
|
||||
return "group";
|
||||
@@ -28,32 +14,17 @@ export function deriveSessionChatTypeFromScopedKey(
|
||||
if (tokens.has("direct") || tokens.has("dm")) {
|
||||
return "direct";
|
||||
}
|
||||
const builtInLegacy = deriveBuiltInLegacySessionChatType(scopedSessionKey);
|
||||
if (builtInLegacy) {
|
||||
return builtInLegacy;
|
||||
}
|
||||
for (const deriveLegacySessionChatType of deriveLegacySessionChatTypes) {
|
||||
const derived = deriveLegacySessionChatType(scopedSessionKey);
|
||||
if (derived) {
|
||||
return derived;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
/**
|
||||
* Best-effort chat-type extraction from session keys across canonical and legacy formats.
|
||||
*/
|
||||
/** Best-effort chat-type extraction from canonical session keys. */
|
||||
export function deriveSessionChatTypeFromKey(
|
||||
sessionKey: string | undefined | null,
|
||||
deriveLegacySessionChatTypes: Array<
|
||||
(scopedSessionKey: string) => SessionKeyChatType | undefined
|
||||
> = [],
|
||||
): SessionKeyChatType {
|
||||
const raw = normalizeLowercaseStringOrEmpty(sessionKey);
|
||||
if (!raw) {
|
||||
return "unknown";
|
||||
}
|
||||
const scoped = parseAgentSessionKey(raw)?.rest ?? raw;
|
||||
return deriveSessionChatTypeFromScopedKey(scoped, deriveLegacySessionChatTypes);
|
||||
return deriveSessionChatTypeFromScopedKey(scoped);
|
||||
}
|
||||
|
||||
@@ -1,65 +1,13 @@
|
||||
import { getBootstrapChannelPlugin } from "../channels/plugins/bootstrap-registry.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../shared/string-coerce.js";
|
||||
import {
|
||||
deriveSessionChatTypeFromKey,
|
||||
type SessionKeyChatType,
|
||||
} from "./session-chat-type-shared.js";
|
||||
import { parseAgentSessionKey } from "./session-key-utils.js";
|
||||
|
||||
export {
|
||||
deriveSessionChatTypeFromKey,
|
||||
type SessionKeyChatType,
|
||||
} from "./session-chat-type-shared.js";
|
||||
|
||||
type LegacySessionChatTypeDeriver = NonNullable<
|
||||
NonNullable<ReturnType<typeof getBootstrapChannelPlugin>>["messaging"]
|
||||
>["deriveLegacySessionChatType"];
|
||||
|
||||
function resolveScopedSessionKey(sessionKey: string | undefined | null): string {
|
||||
const raw = normalizeLowercaseStringOrEmpty(sessionKey);
|
||||
if (!raw) {
|
||||
return "";
|
||||
}
|
||||
return parseAgentSessionKey(raw)?.rest ?? raw;
|
||||
}
|
||||
|
||||
function collectLegacyChatTypeCandidatePluginIds(scopedSessionKey: string): string[] {
|
||||
const ids = new Set<string>();
|
||||
const firstToken = scopedSessionKey.split(":").find(Boolean);
|
||||
if (firstToken) {
|
||||
ids.add(firstToken);
|
||||
}
|
||||
if (scopedSessionKey.includes("@g.us")) {
|
||||
ids.add("whatsapp");
|
||||
}
|
||||
return Array.from(ids);
|
||||
}
|
||||
|
||||
function derivePluginLegacySessionChatType(
|
||||
scopedSessionKey: string,
|
||||
deriveLegacySessionChatType: LegacySessionChatTypeDeriver,
|
||||
): SessionKeyChatType | undefined {
|
||||
if (!deriveLegacySessionChatType) {
|
||||
return undefined;
|
||||
}
|
||||
return deriveLegacySessionChatType(scopedSessionKey);
|
||||
}
|
||||
|
||||
export function deriveSessionChatType(sessionKey: string | undefined | null): SessionKeyChatType {
|
||||
const builtInType = deriveSessionChatTypeFromKey(sessionKey);
|
||||
if (builtInType !== "unknown") {
|
||||
return builtInType;
|
||||
}
|
||||
|
||||
const scopedSessionKey = resolveScopedSessionKey(sessionKey);
|
||||
for (const pluginId of collectLegacyChatTypeCandidatePluginIds(scopedSessionKey)) {
|
||||
const derived = derivePluginLegacySessionChatType(
|
||||
scopedSessionKey,
|
||||
getBootstrapChannelPlugin(pluginId)?.messaging?.deriveLegacySessionChatType,
|
||||
);
|
||||
if (derived) {
|
||||
return derived;
|
||||
}
|
||||
}
|
||||
return "unknown";
|
||||
return deriveSessionChatTypeFromKey(sessionKey);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user